博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
EntityFramework Linq to Entities Left join and filter Include
阅读量:4914 次
发布时间:2019-06-11

本文共 2793 字,大约阅读时间需要 9 分钟。

Linq to Entity 经常有人问能不能实现对Include的内容进行where过滤的Left join,返回的结果集是同时满足主表和子表过滤条件的数据。 答案是可以,但必须使用Select匿名对象,有时候我们希望我们的导航属性里只返回过滤过的对象。

麻烦但却可以实现,不过只推荐使用在取数据的情况下,数据获取完Context最好销毁以免引起混淆。原因是导航属性其实只是用来获取所有关联数据,代表的是一个关系,在Delay Load模式下更是如此。我们返回的结果不应该用导航属性来存储,

不过人总是懒的,所有这样用也有道理。

举个例子:一个主表Patron 与 从表 PatronIdentification

现在我要取出满足PatronName = A 的Patron 以及所有这些Patron相关的IdentificationNumber = aaaa 的 PatronIdentification。返回的结果集必须是一个List<Patron>

可以这样写:

using (BE50Beta_AdminEntities1 context = new BE50Beta_AdminEntities1())            {                List
list = new List
(); context.Patron.Include(p => p.PatronIdentification).Where(p=>p.PatronName=="A").Select(p => new { Patron = p, PatronIdentification = p.PatronIdentification.Where(k => k.IdentificatinNumber == "aaaa") }).ToList().ForEach( p=>{p.Patron.PatronIdentification = p.PatronIdentification.ToList(); resultPatron.Add(p.Patron);} ); }
View Code

这样返回的结果集就是所有PatronName= A 的 Patron 及 IdentificationNumber = aaaa的PatronIdentification 记录

但是这时得到的是个匿名类型对象,我们实在不愿意再花时间定于一个新类去解析,我们想把相关的PatronIdentification List 放到该Patron的导航属性下,于是我们在ForEach里对Patron导航属性重新赋了值,并最终将结果集加入到一个符合返回类型的List中

不要天真的以为不用ForEach时重新对导航属性赋值,虽然这个时候,匿名对象中的Patron就是Patron类型,且PatronIdentification导航属性已经有只值了,也许就是你过滤出来的结果。但千万记住他们是不一样的。

导航属性不仅加载你本次搜索出来的结果,而且还加载已经存在于Context中的结果。所以假如在查询这个从表前你已经一次性查询过整个从表了,那么恭喜你这个导航属性将永远是所有集而不是你想过滤得到的结果。

 

最后,由Sql Profile可得生成的脚本如下:

SELECT [Project1].[PatronID] AS [PatronID], [Project1].[PatronNumber] AS [PatronNumber], [Project1].[PatronName] AS [PatronName], [Project1].[IsActive] AS [IsActive], [Project1].[C1] AS [C1], [Project1].[PatronIdentificatinID] AS [PatronIdentificatinID], [Project1].[PatronID1] AS [PatronID1], [Project1].[CountryID] AS [CountryID], [Project1].[IdentificatinNumber] AS [IdentificatinNumber]FROM ( SELECT     [Extent1].[PatronID] AS [PatronID],     [Extent1].[PatronNumber] AS [PatronNumber],     [Extent1].[PatronName] AS [PatronName],     [Extent1].[IsActive] AS [IsActive],     [Extent2].[PatronIdentificatinID] AS [PatronIdentificatinID],     [Extent2].[PatronID] AS [PatronID1],     [Extent2].[CountryID] AS [CountryID],     [Extent2].[IdentificatinNumber] AS [IdentificatinNumber],     CASE WHEN ([Extent2].[PatronIdentificatinID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]    FROM  [dbo].[Patron] AS [Extent1]    LEFT OUTER JOIN [dbo].[PatronIdentification] AS [Extent2] ON ([Extent1].[PatronID] = [Extent2].[PatronID]) AND ('aaaa' = [Extent2].[IdentificatinNumber])    WHERE 'A' = [Extent1].[PatronName])  AS [Project1]ORDER BY [Project1].[PatronID] ASC, [Project1].[C1] ASC
View Code

可见,脚本正常,不会影响性能

 

转载于:https://www.cnblogs.com/vincentsun1234/archive/2013/05/19/3087730.html

你可能感兴趣的文章
Linq C#增删改查
查看>>
[转]第一章 Windows Shell是什么 【来源:http://blog.csdn.net/wangqiulin123456/article/details/7987862】...
查看>>
iOS获取设备UUID和IDFA
查看>>
模糊查询
查看>>
linux 出现:-bash-3.2$提示符
查看>>
jsp电子商务 购物车实现之二 登录和分页篇
查看>>
科普:搜索引擎的基本工作原理
查看>>
Docker Compose 原理
查看>>
mongodb index 的background 及集群的索引建立
查看>>
判断两个控件在同一个Window上是否有重叠
查看>>
Android+Jquery Mobile学习系列(3)-创建Android项目
查看>>
android:inputType参数类型说明
查看>>
android 抽屉式滑动demo
查看>>
Swift语言Storyboard教程:第一部分
查看>>
unload事件Ajax提交问题
查看>>
代码工程flex不显示GIF图片问题
查看>>
Kotlin 初窥门径[2]:流程控制
查看>>
Android利用Socket与硬件通信之智能家居APP
查看>>
Idea中提交SVN或git时,忽略某些文件不提交
查看>>
20135236、20135206第一次试验报告
查看>>