2010-11-09 53 views
2

谁能帮我在评估为什么下面的代码无法正常工作。在使用IObjectset时,我使用通用扩展方法来实现Include。在我们的存储库中,我们看到这不能正确返回,所以我已经在测试应用程序中隔离了代码,如下所示。我还包括基于界面的上下文,如果这可能是相关的和相关模型部分的屏幕截图。这发生在IObjectSet属性上的所有Include上,而不仅仅是我为这个例子选择的DPASelections。麻烦与包括延长对IObjectSet不工作

如果我更新上下文返回的ObjectSet(仍然使用POCO实体),而不是IObjectSet这一切工作正常。当使用IObjectSet和扩展方法并遍历代码时,我看到扩展方法通过调用我们正在执行的ObjectQuery而正确完成,但包含的实体从未在图上返回。如上所述,当我没有接口Context并返回ObjectSet属性,因此在ObjectSet上直接调用Include时,此功能完美无缺。

我没有收到关于执行查询的任何错误,所以这是不一样的,其是指编译查询的SO其他一些问题。

有其他人遇到的问题与此扩展方法实现或任何人能发现我在做什么错在这里?

任何帮助,非常感谢。

 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")); } 
    } 
} 

和模型... alt text

+0

我使用完全相同的设置,并能正常工作,我(没有真正帮助你,但认为Id提及)。你有没有加入代码 - 你的扩展方法叫做,你运行profiler跟踪等。 – RPM1984 2010-11-09 10:05:21

+0

分机。方法代码运行良好并调用数据库,但生成的查询只是忽略了Includes并仅返回候选。 – 2010-11-09 11:58:33

+0

@Daz刘易斯 - 你尝试'.INCLUDE(“DPASelections”)包括(“DPASelections.DPAOption”)'我不认为你可以直接去一个双嵌套导航。 (我可能是错的)。保持简单,'context.Candidates.Include(“Grade”)。FirstOrDefault()'工作吗? – RPM1984 2010-11-09 23:34:18

回答

1

,我需要objectQuery = objectQuery.Include(path);

0

:在.NET框架4.0更换objectQuery.Include(path);有一个内置的Extentionmethod为Include 只是添加System.Data.Entity命名空间。

它采用反射 - 在这里是如何工作的:

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 
    }); 
}