任何人都可以帮我评估下面代码无效的原因。我在使用IObjectset时使用公共扩展方法来实现Include。在我们的存储库中,我们看到这没有正确返回所以我已经在测试应用程序中隔离了代码,如下所示。如果这可能证明是相关的,我还包括基于接口的Context,以及相关模型部分的屏幕截图。 IObjectSet属性上的所有包含都会发生这种情况,而不仅仅是我为此示例选择的DPASelections。
如果我更新上下文以返回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")); }
}
}
模特......
答案 0 :(得分:1)
我需要将objectQuery.Include(path);
替换为objectQuery = objectQuery.Include(path);
答案 1 :(得分:0)
在.Net framework 4.0中,Include
有一个内置的Extentionmethod
只需添加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
});
}