开发者

Trouble with Include extension on IObjectSet not working

Could anyone help me in assessing why the code below doesn't work. I'm using the common extension method for implementing Include when using IObjectset. In our repositories we were seeing this not returning correctly so I've isolated the code in test app as below. I've also included the interface based Context if this may prove relevant and a screenshot of the relevant model section. This occurs for all 开发者_如何学CIncludes on IObjectSet properties not just the DPASelections one I've chosen for this example.

If I update the context to return ObjectSet (still using the POCO entities) rather than IObjectSet it all works fine. When using IObjectSet and the extension method and step through the code I see that the extension method is completing correctly with a call to the ObjectQuery we're casting to but the included entities are never returned on the graph. As said, this works perfectly when I don't interface out the Context and return ObjectSet properties hence calling Include directly on ObjectSet.

I'm not getting any errors on executing the query so this isn't the same as several other questions on SO which refer to compiled queries.

Has anyone else experienced problems with this extension method implementation or can anyone spot what I'm doing wrong here?

Any help very much appreciated.

        static void Main(string[] args)
    {
        using (var context = new AssocEntities())
        {
            context.ContextOptions.LazyLoadingEnabled = false;
            Candidate candidate = context.Candidates
                                        .Include("DPASelections.DPAOption")
                                        .SingleOrDefault(c => c.Number == "N100064");

            //Count is 0 when using ext. method and IObjectSet through AssocContext but correct when using Include
            //on ObjectSet through AssocContext
            Console.WriteLine("DPASelection count = {0}",candidate.DPASelections.Count);

            //This is always null when using IObjectSet and ext. method but populated
            //when using Include on ObjectSet
            var option = candidate.DPASelections.First().DPAOption;

            Console.WriteLine("First DPAOption = {0} : {1}",option.Id,option.Text);

        }

        Console.ReadLine();
    }
}

public static class Extensions
{
    public static IQueryable<TSource> Include<TSource>(this IQueryable<TSource> source, string path)
    {
        var objectQuery = source as ObjectQuery<TSource>;

        if (objectQuery != null)
        {
            objectQuery.Include(path);
        }

        return source;
    }
}

//Subset of custom context implementing IObjectSet as returns.
//Works fine when I return ObjectSet rather than IObjectSet and use
//the Include method directly
public partial class AssocEntities : ObjectContext
{
    public const string ConnectionString = "name=AssocEntities";
    public const string ContainerName = "AssocEntities";

    #region Constructors

    public AssocEntities()
        : base(ConnectionString, ContainerName)
    {
        this.ContextOptions.LazyLoadingEnabled = true;
    }

    public AssocEntities(string connectionString)
        : base(connectionString, ContainerName)
    {
        this.ContextOptions.LazyLoadingEnabled = true;
    }

    public AssocEntities(EntityConnection connection)
        : base(connection, ContainerName)
    {
        this.ContextOptions.LazyLoadingEnabled = true;
    }

    #endregion

    #region IObjectSet Properties

    public IObjectSet<Address> Addresses
    {
        get { return _addresses ?? (_addresses = CreateObjectSet<Address>("Addresses")); }
    }
    private IObjectSet<Address> _addresses;

    public IObjectSet<Answer> Answers
    {
        get { return _answers ?? (_answers = CreateObjectSet<Answer>("Answers")); }
    }
    private IObjectSet<Answer> _answers;

    public IObjectSet<Candidate> Candidates
    {
        get { return _candidates ?? (_candidates = CreateObjectSet<Candidate>("Candidates")); }
    }
}

And the model...

Trouble with Include extension on IObjectSet not working


I needed to replace objectQuery.Include(path); with objectQuery = objectQuery.Include(path);


In .Net framework 4.0 there is a build-in Extentionmethod for Include just add the System.Data.Entity namespace.

It uses reflection - here is how it works:

private static T CommonInclude<T>(T source, string path)
{
  MethodInfo method = source.GetType().GetMethod("Include", DbExtensions.StringIncludeTypes);
  if (!(method != (MethodInfo) null) || !typeof (T).IsAssignableFrom(method.ReturnType))
    return source;
  return (T) method.Invoke((object) source, new object[1]
  {
    (object) path
  });
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜