ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 实体框架6延迟加载奇怪

2019-07-08 07:18:36  阅读:191  来源: 互联网

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


我有一个连接到实体框架的poco类.该类称为PersonalizationCatalogPrice.这个类有一个名为Pricelevel的子对象,它没有虚拟关键字.因为这(基于我的理解)这个对象永远不应该延迟加载,应该返回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对象也会加载.

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,因为它上面没有虚拟关键字,然后实体框架按预期工作. (EF 6)

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

谢谢你的帮助.

解决方法:

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

在某些情况下我可以想到,这种期望不会得到满足.

第一种情况是,如果您以急切的方式加载数据.哪个将明确使用Include().此行为也称为急切加载.由于急切加载确实加载了允许的所有内容,因此不需要通过调用ToArray()或ToList()或其他触发枚举的方法来枚举集合.
将加载每个非延迟属性,包括其所有值类型属性和非延迟属性.

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

如果您通过调用Load()显式加载了该实体,或者它是从其他先前的查询返回的,那么情况也是如此.

为了验证是否是这种情况,您可以使用AsNoTracking()扩展方法.除了其他效果之外,未跟踪的实体将不会彼此链接.

标签:c,linq,entity-framework,entity-framework-6,lazy-loading
来源: https://codeday.me/bug/20190708/1399625.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有