3

我在我的应用程序中使用 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
                }
            }
        }
4

3 回答 3

8

为了使延迟加载起作用,EF5 必须做一些棘手的工作。在运行时,他们创建代理类,这些代理类派生自您的模型类。在这些代理类中,它们覆盖导航属性以实现延迟加载机制。

您的SubEntity2SubEntity3属性是虚拟的,因此可以覆盖它们。您的SubEntities属性不是虚拟的 - EF5 无法覆盖此属性以实现延迟加载。

当您使您的SubEntities财产虚拟化时,它应该可以工作。

于 2013-03-13T12:59:52.330 回答
0

要启用延迟加载,您必须创建您的字段virtual,这是真的。但是你还有另一个问题。你有你的ICollection<SubEntity4>as private。这使映射器无法访问您的字段。我遇到了类似的问题,并询问如何将实体的私有字段设置为对映射器可见。答案是——“不可能”!这是一个链接:

如何启用映射实体的私有属性

所以就这样做:

   public virtual ICollection<SubEntity4> SubEntities {get;set};

并移除您的财产。

于 2013-03-13T13:14:23.727 回答
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; }
}
于 2013-03-13T13:00:01.240 回答