我在我的应用程序中使用EF5(代码优先)。 我有一个包含一些延迟加载字段的表。
public class TestEntity
{
public int Id { get; set; }
public virtual TestEntity2 SubEntity2 { get; set; }
public virtual TestEntity3 SubEntity3 { get; set; }
private ICollection<SubEntity4> _subEntities;
public ICollection<SubEntity4> SubEntities
{
get { return _subEntities ?? (_subEntities = new Collection<SubEntity4>()); }
protected set { _subEntities = value; }
}
}
当我从数据库SubEntity2读取此内容时,SubEntity3正在加载正常但SubEntities集合不会加载,它始终保持Count = 0。所以我强迫这样加载:
db.Entry(queryResult).Collection(rr => rr.SubEntities).Load();
但据我所知,这个集合应该在第一次调用时由EF自动加载,就像SubEntity2和SubEntity3一样。为什么不与集合合作?
我用来读取数据库的代码示例:
using (var db = new TestContext(_connection, false))
{
var query = from r in db.SubEntities
where r.Id == 10
select r;
var queryRes = query.FirstOrDefault();
if (queryRes != null)
{
if (queryRes.FederalRegion != null)
{
// Do something
}
foreach (var dbEnt in queryRes.SubEntities)
{
// Do something
}
}
}
答案 0 :(得分:8)
为了使延迟加载工作,EF5必须做一些棘手的工作。在运行时,它们创建代理类,这些代理类派生自您的模型类。在这些代理类中,它们覆盖导航属性以实现延迟加载机制。
您的SubEntity2
和SubEntity3
属性是虚拟的,因此可以覆盖它们。您的SubEntities
属性不是虚拟的 - EF5无法覆盖此属性以实现延迟加载。
当您将SubEntities
属性设为虚拟时,它应该可以正常工作。
答案 1 :(得分:0)
你所描述的“子实体”(集合)本质上是懒惰的。如果您不希望它们延迟加载,则应使用.Include(x=> x.SubEntitiesCollectionName)
扩展方法。
修改强>
你的课应该是这样的:
public class TestEntity
{
public int Id { get; set; }
public virtual TestEntity2 SubEntity2 { get; set; }
public virtual TestEntity3 SubEntity3 { get; set; }
public virtual ICollection<SubEntity4> SubEntities { get; set; }
}
答案 2 :(得分:0)
要启用延迟加载,您必须创建字段virtual
,这是真的。但是你还有另一个问题。您的ICollection<SubEntity4>
为private
。这使得您的字段无法访问映射器。我有类似的问题,并询问如何设置实体的私有字段对于映射器是可见的。答案是 - “这是不可能的”!这是一个链接:
How to enable mapping the private property of the entity
所以就这样做:
public virtual ICollection<SubEntity4> SubEntities {get;set};
并删除你的财产。