如果不想延迟加载,可以通过设置:context.Configuration.LazyLoadingEnabled = false;或查询时加上AsNoTracking()方法即可。

如果不想生成代理,可以通过设置:context.Configuration.ProxyCreationEnabled = false;

注意当context.Configuration.ProxyCreationEnabled = false;时延迟加载也就不生效,原理很简单,因为没有代理。

当禁用延迟加载后,关联属性(导航属性)不会被实例化,这时如果需要实例化该属性,则需要通过Include方法,意为显式加载(也有人称为饥饿加载),具体的用法也可参见我之前的文章:http://www.cnblogs.com/zuowj/p/4514230.html

好了有了上面知识的了解,我们想实现一次性加载所有内容包含关联属性的值,且不要生成代理对象,就很简单了,我项目中的语句如下:

            var context = new LocalDbEntities();
context.Configuration.LazyLoadingEnabled = false;
context.Configuration.ProxyCreationEnabled = false;
result=context.Set<TA_CWTransferRequestInfo>().Where(t => true).Include(t => t.TA_CWBankAccountInfo).GroupBy(t => t.TA_CWBankAccountInfo.bkcode)
.ToDictionary(gp => gp.Key, gp => gp.ToList());

代码简单说明一下,TA_CWTransferRequestInfo有一个关联属性TA_CWBankAccountInfo,我想实现依据TA_CWBankAccountInfo.bkcode来分组并存入Dictionary中,最后我需要用到TA_CWTransferRequestInfo.TA_CWBankAccountInfo属性的信息,原本以为没有问题,但实际使用时,却报错:无法对 null 引用执行运行时绑定,经DEBUG时发现TA_CWTransferRequestInfo.TA_CWBankAccountInfo=null,这就有点不解了,明明我使用了Include,为何没有加载呢?不解之余查看了一下上述LINQ生成的SQL语句如下:

SELECT
[Project2].[C1] AS [C1],
[Project2].[bkcode] AS [bkcode],
[Project2].[C2] AS [C2],
[Project2].[id] AS [id],
[Project2].[fromactacn] AS [fromactacn],
[Project2].[toactacn] AS [toactacn],
[Project2].[toibkn] AS [toibkn],
[Project2].[toname] AS [toname],
[Project2].[toaddr] AS [toaddr],
[Project2].[tobknm] AS [tobknm],
[Project2].[tobkcode] AS [tobkcode],
[Project2].[trnamt] AS [trnamt],
[Project2].[trncur] AS [trncur],
[Project2].[priolv] AS [priolv],
[Project2].[furinfo] AS [furinfo],
[Project2].[trfdate] AS [trfdate],
[Project2].[trftime] AS [trftime],
[Project2].[comacn] AS [comacn],
[Project2].[field1] AS [field1],
[Project2].[field2] AS [field2],
[Project2].[field3] AS [field3],
[Project2].[field4] AS [field4],
[Project2].[field5] AS [field5],
[Project2].[field6] AS [field6],
[Project2].[field7] AS [field7],
[Project2].[field8] AS [field8],
[Project2].[processing] AS [processing],
[Project2].[transtype] AS [transtype],
[Project2].[trfmode] AS [trfmode],
[Project2].[createdt] AS [createdt],
[Project2].[lastupdatedt] AS [lastupdatedt],
[Project2].[lastrspid] AS [lastrspid],
[Project2].[rowversion] AS [rowversion],
[Project2].[lyd_guid] AS [lyd_guid]
FROM ( SELECT
[Distinct1].[bkcode] AS [bkcode],
1 AS [C1],
[Join2].[id] AS [id],
[Join2].[fromactacn] AS [fromactacn],
[Join2].[toactacn] AS [toactacn],
[Join2].[toibkn] AS [toibkn],
[Join2].[toname] AS [toname],
[Join2].[toaddr] AS [toaddr],
[Join2].[tobknm] AS [tobknm],
[Join2].[tobkcode] AS [tobkcode],
[Join2].[trnamt] AS [trnamt],
[Join2].[trncur1] AS [trncur],
[Join2].[priolv] AS [priolv],
[Join2].[furinfo] AS [furinfo],
[Join2].[trfdate] AS [trfdate],
[Join2].[trftime] AS [trftime],
[Join2].[comacn] AS [comacn],
[Join2].[field11] AS [field1],
[Join2].[field21] AS [field2],
[Join2].[field31] AS [field3],
[Join2].[field41] AS [field4],
[Join2].[field51] AS [field5],
[Join2].[field6] AS [field6],
[Join2].[field7] AS [field7],
[Join2].[field8] AS [field8],
[Join2].[processing] AS [processing],
[Join2].[transtype] AS [transtype],
[Join2].[trfmode] AS [trfmode],
[Join2].[createdt] AS [createdt],
[Join2].[lastupdatedt1] AS [lastupdatedt],
[Join2].[lastrspid] AS [lastrspid],
[Join2].[rowversion1] AS [rowversion],
[Join2].[lyd_guid] AS [lyd_guid],
CASE WHEN ([Join2].[priolv] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2]
FROM (SELECT DISTINCT
[Extent2].[bkcode] AS [bkcode]
FROM [dbo].[TA_CWTransferRequestInfo] AS [Extent1]
INNER JOIN [dbo].[TA_CWBankAccountInfo] AS [Extent2] ON [Extent1].[fromactacn] = [Extent2].[actacn] ) AS [Distinct1]
LEFT OUTER JOIN (SELECT [Extent3].[id] AS [id], [Extent3].[fromactacn] AS [fromactacn], [Extent3].[toactacn] AS [toactacn], [Extent3].[toibkn] AS [toibkn], [Extent3].[toname] AS [toname], [Extent3].[toaddr] AS [toaddr], [Extent3].[tobknm] AS [tobknm], [Extent3].[tobkcode] AS [tobkcode], [Extent3].[trnamt] AS [trnamt], [Extent3].[trncur] AS [trncur1], [Extent3].[priolv] AS [priolv], [Extent3].[furinfo] AS [furinfo], [Extent3].[trfdate] AS [trfdate], [Extent3].[trftime] AS [trftime], [Extent3].[comacn] AS [comacn], [Extent3].[field1] AS [field11], [Extent3].[field2] AS [field21], [Extent3].[field3] AS [field31], [Extent3].[field4] AS [field41], [Extent3].[field5] AS [field51], [Extent3].[field6] AS [field6], [Extent3].[field7] AS [field7], [Extent3].[field8] AS [field8], [Extent3].[processing] AS [processing], [Extent3].[transtype] AS [transtype], [Extent3].[trfmode] AS [trfmode], [Extent3].[createdt] AS [createdt], [Extent3].[lastupdatedt] AS [lastupdatedt1], [Extent3].[lastrspid] AS [lastrspid], [Extent3].[rowversion] AS [rowversion1], [Extent3].[lyd_guid] AS [lyd_guid], [Extent4].[bkcode] AS [bkcode]
FROM [dbo].[TA_CWTransferRequestInfo] AS [Extent3]
INNER JOIN [dbo].[TA_CWBankAccountInfo] AS [Extent4] ON [Extent3].[fromactacn] = [Extent4].[actacn] ) AS [Join2] ON ([Distinct1].[bkcode] = [Join2].[bkcode]) OR (1 = 0)
) AS [Project2]
ORDER BY [Project2].[bkcode] ASC, [Project2].[C2] ASC

看到这个SQL语句我也是醉了,与我的本意完全不同,从上面的SQL语句可以看出来:它虽然关联时有用到[TA_CWBankAccountInfo],但最后只查出[TA_CWTransferRequestInfo]的字段,当然也就无法实例化关联的TA_CWBankAccountInfo属性了,最后得出结论,当使用GroupBy+ToDictionary时,Include方法无效。

鉴于上述结论,我将上述语句稍微作了一下调整,就成功通过测试了,更改后的语句:

            var context = new LocalDbEntities();
context.Configuration.LazyLoadingEnabled = false;
context.Configuration.ProxyCreationEnabled = false;
return context.Set<TA_CWTransferRequestInfo>().Where(t => true).Include(t => t.TA_CWBankAccountInfo).ToList().GroupBy(t => t.TA_CWBankAccountInfo.bkcode)
.ToDictionary(gp => gp.Key, gp => gp.ToList());

发现区别了没有?我只是在Include后加了一个ToList()方法就可以了,目的是先从数据库查询出符合条件的数据(包含关联的数据),然后再在本地进行GroupBy操作,可以看一下生成的SQL语句:

SELECT
[Extent1].[priolv] AS [priolv],
[Extent1].[id] AS [id],
[Extent1].[fromactacn] AS [fromactacn],
[Extent1].[toactacn] AS [toactacn],
[Extent1].[toibkn] AS [toibkn],
[Extent1].[toname] AS [toname],
[Extent1].[toaddr] AS [toaddr],
[Extent1].[tobknm] AS [tobknm],
[Extent1].[tobkcode] AS [tobkcode],
[Extent1].[trnamt] AS [trnamt],
[Extent1].[trncur] AS [trncur],
[Extent1].[furinfo] AS [furinfo],
[Extent1].[trfdate] AS [trfdate],
[Extent1].[trftime] AS [trftime],
[Extent1].[comacn] AS [comacn],
[Extent1].[field1] AS [field1],
[Extent1].[field2] AS [field2],
[Extent1].[field3] AS [field3],
[Extent1].[field4] AS [field4],
[Extent1].[field5] AS [field5],
[Extent1].[field6] AS [field6],
[Extent1].[field7] AS [field7],
[Extent1].[field8] AS [field8],
[Extent1].[processing] AS [processing],
[Extent1].[transtype] AS [transtype],
[Extent1].[trfmode] AS [trfmode],
[Extent1].[createdt] AS [createdt],
[Extent1].[lastupdatedt] AS [lastupdatedt],
[Extent1].[lastrspid] AS [lastrspid],
[Extent1].[rowversion] AS [rowversion],
[Extent1].[lyd_guid] AS [lyd_guid],
[Extent2].[actacn] AS [actacn],
[Extent2].[ibknum] AS [ibknum],
[Extent2].[actnam] AS [actnam],
[Extent2].[bknm] AS [bknm],
[Extent2].[bkcode] AS [bkcode],
[Extent2].[addr] AS [addr],
[Extent2].[actacnas] AS [actacnas],
[Extent2].[trncur] AS [trncur1],
[Extent2].[field1] AS [field11],
[Extent2].[field2] AS [field21],
[Extent2].[field3] AS [field31],
[Extent2].[field4] AS [field41],
[Extent2].[field5] AS [field51],
[Extent2].[lastupdatedt] AS [lastupdatedt1],
[Extent2].[rowversion] AS [rowversion1]
FROM [dbo].[TA_CWTransferRequestInfo] AS [Extent1]
INNER JOIN [dbo].[TA_CWBankAccountInfo] AS [Extent2] ON [Extent1].[fromactacn] = [Extent2].[actacn]

这个SQL语句是既简洁又明了,符合我的意图,从遇到的这个坑得到启示,有时不要把问题复杂化,换个角度看问题或许能找到更好的解决办法。

分享使用Entity Framework的一个坑:Include无效的更多相关文章

  1. Entity Framework的一个坑

    由于业务需要写了一个批量数据导入工具.中间踩了一个坑 问: 1. SaveChange 实体A 发生pk冲突,异常了.2.记录日志3.不让退出程序,继续处理下一个实体4.Add新的实体B5.再次调用S ...

  2. Entity Framework Core的坑:Skip/Take放在Select之前造成Include的实体全表查询

    今天将一个迁移至 ASP.NET Core 的项目放到一台 Linux 服务器上试运行.站点启动后,浏览器打开一个页面一直处于等待状态.接着奇怪的事情发生了,整个 Linux 服务器响应缓慢,ssh命 ...

  3. Entity Framework DbSet<T>之Include方法与IQueryable<T>扩展方法Include的使用

    Entity Framework使用Code First方式时,实体之间已经配置好关系,根据实际情况某些情况下需要同时获取导航属性,比如获取商品的同时需要获取分类属性(导航属性),或者基于优化方面考虑 ...

  4. 分享基于Entity Framework的Repository模式设计(附源码)

    关于Repository模式,在这篇文章中有介绍,Entity Framework返回IEnumerable还是IQueryable? 这篇文章介绍的是使用Entity Framework实现的Rep ...

  5. 分享关于Entity Framework 进行CRUD操作实验的结果

    我们在使用Entity Framework框架进行CRUD时,经常会出现各种各样的错误,下面请看我的实验结果. 以下是只用一个上下文对象进行操作: 第一次: BlogDbContext blog = ...

  6. Entity Framework的一个实例

    环境:Visual studio2013+sql server本地数据库 创建一个C#应用程序,首先在nuget中添加Entity Framework 接下来的工作分为四个主要部分: 第一部分:App ...

  7. Entity Framework Core的坑,Select后再对导航属性进行查询或Select前进行Skip/Take

    把asp.net core的项目发布到ubuntu上了,运行的时候出现了如下警告: warn: Microsoft.EntityFrameworkCore.Query[20500] The LINQ ...

  8. 第三篇 Entity Framework Plus 之 Query Cache

    离上一篇博客,快一周,工作太忙,只能利用休息日来写一些跟大家分享,Entity Framework Plus 组件系列文章,之前已经写过两篇 第一篇 Entity Framework Plus 之 A ...

  9. Entity Framework Core 1.1 Preview 1 简介

    实体框架核心(EF Core)是Entity Framework的一个轻量级,可扩展和跨平台版本. 10月25日,Entity Framework Core 1.1 Preview 1发布了. 升级到 ...

随机推荐

  1. SQL入门经典(四)之创建和修改数据表

    本章主要讲如何使用脚本创建数据库:如何使用脚本创建表:如何删除对象和修改对象. CREATE 语句:CREATE <object type> <onject name> 创建数 ...

  2. 字符串反混淆实战 Dotfuscator 4.9 字符串加密技术应对策略

    因为手头需要使用一个第三方类库,网络上又找不到它的可用的版本,于是只好自己动手.这个类库使用了Dotfuscator 加密,用.NET Reflector加载程序集, 看到的字符串是乱码,如下面的代码 ...

  3. Restful.Data v2.0发布,谢谢你们的支持和鼓励

    v1.0发布后,承蒙各位博友们的热心关注,也给我不少意见和建议,在此我真诚的感谢 @冰麟轻武 等朋友,你们的支持和鼓励,是这个开源项目最大的推动力. v2.0在除了细枝末节外,在功能上主要做了一下更新 ...

  4. web前端职业规划(转)

    关于一个WEB前端的职业规划,其实是有各种的答案,没有哪种答案是完全正确的,全凭自己的选择,只要是自己选定了, 坚持去认真走,就好.在这里,我只是简要说一下自己对于这块儿内容的理解.有一个观点想要分享 ...

  5. C#Light Unity逻辑热更新解决方案0.20 发布

    之前一直是Beta,这次已经实际运用到项目中间了,去掉beta状态 在项目中使用面对一些新的问题,还有以前没注意的bug. 更新列表 一.增加类中类的支持 二.增加对foreach的支持,同C#语法 ...

  6. as3 同屏1000+动画,不掉帧。解决方案。

    原理就是在一个enterframe里面,把1000个对象画到一个bitmapdata,然后交给舞台显示.

  7. Axis 1 https(SSL) client 证书验证错误ValidatorException workaround

    Axis 1.x 编写的client在测试https的webservice的时候, 由于client 代码建立SSL连接的时候没有对truststore进行设置,在与https部署的webservic ...

  8. java.util.Properties

    1 Properties文件中分隔符及空格的处理 因为 Properties 继承于 Hashtable,所以可对 Properties 对象应用 put 和 putAll 方法.但强烈反对使用这两个 ...

  9. 奇怪的BUG

    熟语说“常在河边走,哪能不湿鞋”,在现实中我想说:“代码写多了,总会遇到奇怪的bug”,遇到bug不可怕,可怕的是不自己不知道这么解决,有些bug能当时解决,有些在自己知识水平提高后知道如何解决.还有 ...

  10. Kafka入门初探+伪集群部署

    Kafka是目前非常流行的消息队列中间件,常用于做普通的消息队列.网站的活性数据分析(PV.流量.点击量等).日志的搜集(对接大数据存储引擎做离线分析). 全部内容来自网络,可信度有待考证!如有问题, ...