c# - Entity Framework 6 延迟加载怪癖

标签 c# linq entity-framework entity-framework-6 lazy-loading

我有一个连接到 Entity Framework 的 poco 类。该类称为 PersonalizationCatalogPrice。这个类有一个名为 Pricelevel 的子对象,它上面没有 virtual 关键字。因此(根据我的理解)这个对象不应该延迟加载并且应该返回 null。但是,我们发现这个对象在以特定方式使用时似乎会加载。

所以基本的类结构是这样的

public class PersonalizationCatalogPrice
    {
        public int PersonalizationCatalogPriceID { get; set; }

        public int PersonalizationCatalogId { get; set; }

        public virtual PersonalizationCatalog PersonalizationCatalog { get; set; }

        public decimal CustomerRetail { get; set; }

        public decimal ConsultantCost { get; set; }

        public decimal PersonalVolume { get; set; }

        public decimal QualifyingVolume { get; set; }

        public int PriceLevelId { get; set; }

        public PriceLevel PriceLevel { get; set; }
}

这是一个例子。在第一行中,我们返回一个 Iqueryable of PersonalizationCatalogPrice 项目。在第二行中,我们有另一个 IQueryable,我们在这个 iQueryable 中使用了 priclevel 对象(参见“contains pcp.pricelevel”这一行)。当我们这样做时,pricelevel 对象会加载,即使它没有 virtual 关键字。

IQueryable<PersonalizationCatalogPrice> allPersPriceRecords = _e2ReposMan.PersonalizationRepository.GetSomeRecords();

//List<PersonalizationCatalogPrice> persprices = allPersPriceRecords.ToList();

var persQuery = from pl in personalizationLines
                join pcp in allPersPriceRecords on pl.Item2.PersonalizationCatalogPriceID equals pcp.PersonalizationCatalogPriceID
                where !HostessPriceLevelTypes().Contains(pcp.PriceLevel.PriceLevelTypeId)
                select pl.Item2.PersonalVolume * pl.Item1;

var openOrdersTotal = (query.Any() ? query.Sum() : 0) + (persQuery.Any() ? persQuery.Sum() : 0);

但是,通过取消注释执行 ToList() 的第二行来修改此代码。使 pricelevel 子对象按预期返回 null,因为它上面没有虚拟关键字,然后 Entity Framework 按我们预期的方式工作。 (英孚 6)

有谁知道为什么我们在不执行 toList() 时能够加载 pricelevel 属性。

感谢您的帮助。

最佳答案

根据您使用的措辞,您似乎希望 PriceLevel 属性在不使用延迟加载时为 null

有一些我能想到的情况,在这些情况下,这种期望不会得到满足。

第一种情况是您以急切的方式加载数据。这将显式使用 Include()。这种行为也称为预加载。由于预先加载确实会加载它允许的所有内容,因此不需要您通过调用 ToArray()ToList() 或其他触发枚举的方法来枚举集合。 将加载所有非惰性属性,包括其所有值类型属性和非惰性属性。

您的代码没有指明这一点,但是如果您在执行显示的代码之前在同一个 DbContext 派生实例上执行此操作,则该属性仍不会为 null。只要有问题的实体已经缓存在您的 DbContext 中,就会发生这种情况。

如果您已通过调用 Load() 显式加载该实体,或者如果它已从其他先前查询返回,则同样如此。

为了验证是否是这种情况,您可以使用 AsNoTracking()扩展方法。未被跟踪的实体将不会相互链接。

关于c# - Entity Framework 6 延迟加载怪癖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31568998/

相关文章:

c# - Linq 获取句子中的单词

c# - 在 Entity Framework 中跨多个表进行选择,从而产生通用的 IQueryable?

entity-framework - SQLite 数据库放置在 UWP 应用中的位置

c# - Entity Framework 不生成 ApplicationUser 外键

c# - 获取属性名称而不通过反射传递它?

c# - Linq - OrderByDescending 和 Take(1),它会返回最大项目吗?

c# - 在 MVC 中发送远程属性的参数

c# - 使用 linq 将 json 字符串解析为对象

c# - NLog 和单元测试

c# - Fetch 和 Query 有什么区别?