EntityFramework嵌套查询的五种方法
这样的双where的语句应该怎么写呢:
var test=MyList.Where(a => a.Flows.Where(b => b.CurrentUser == “”)
下面我就说说这个问题,想想有几种方法。先来做一下准备工作,我们使用最简单的模型Category和Post
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class Category { public int Id { get ; set ; } public string Name { get ; set ; } public virtual ICollection Posts { get ; set ; } } public class Post { public int Id { get ; set ; } public string Author { get ; set ; } public string Title { get ; set ; } public int CategoryId { get ; set ; } public Category Category { get ; set ; } } |
把上面的问题转换成这个模型解释就是:查询含有某个Author写的Post的Category。
这个问题如果直接使用SQL来写的话很简单:
1
2
3
|
select distinct (c.Id),c. Name from Categories c inner join Posts p on p.CategoryId=c.Id where p.Author=N 'cj' |
下面依次来看EntityFramework的四种实现方法。
第一种,使用Any
1
|
var list = ctx.Categories.Where(t => t.Posts.Any(s => s.Author == "cj" )); |
生成的SQL语句如下:
1
2
3
4
5
6
7
8
9
|
SELECT [Extent1].[Id] AS [Id], [Extent1].[ Name ] AS [ Name ] FROM [dbo].[Categories] AS [Extent1] WHERE EXISTS ( SELECT 1 AS [C1] FROM [dbo].[Posts] AS [Extent2] WHERE ([Extent1].[Id] = [Extent2].[CategoryId]) AND (N 'cj' = [Extent2].[Author]) ) |
第二种,使用Select
1
|
var list = ctx.Posts.Where(t => t.Author == "cj" ).Select(t => t.Category).Distinct(); |
生成的SQL语句如下:
1
2
3
4
5
6
7
8
9
10
|
SELECT [Distinct1].[Id] AS [Id], [Distinct1].[ Name ] AS [ Name ] FROM ( SELECT DISTINCT [Extent2].[Id] AS [Id], [Extent2].[ Name ] AS [ Name ] FROM [dbo].[Posts] AS [Extent1] INNER JOIN [dbo].[Categories] AS [Extent2] ON [Extent1].[CategoryId] = [Extent2].[Id] WHERE N 'cj' = [Extent1].[Author] ) AS [Distinct1] |
第三种,使用SelectMany
1
2
3
4
5
|
var list = ctx.Categories.SelectMany(t => t.Posts, (category, post) => new { category, post }).Where(t => t.post.Author == "cj" ).Select(t => t.category).Distinct(); |
生成的SQL语句如下:
1
2
3
4
5
6
7
8
9
10
|
SELECT [Distinct1].[Id] AS [Id], [Distinct1].[ Name ] AS [ Name ] FROM ( SELECT DISTINCT [Extent1].[Id] AS [Id], [Extent1].[ Name ] AS [ Name ] FROM [dbo].[Categories] AS [Extent1] INNER JOIN [dbo].[Posts] AS [Extent2] ON [Extent1].[Id] = [Extent2].[CategoryId] WHERE N 'cj' = [Extent2].[Author] ) AS [Distinct1] |
第四种,还是使用SelectMany
1
|
var list = ctx.Categories.SelectMany(t => t.Posts).Where(t => t.Author == "cj" ).Select(t => t.Category).Distinct(); |
生成的SQL语句如下:
1
2
3
4
5
6
7
8
9
10
|
SELECT [Distinct1].[Id] AS [Id], [Distinct1].[ Name ] AS [ Name ] FROM ( SELECT DISTINCT [Extent1].[Id] AS [Id], [Extent1].[ Name ] AS [ Name ] FROM [dbo].[Categories] AS [Extent1] INNER JOIN [dbo].[Posts] AS [Extent2] ON ([Extent1].[Id] = [Extent2].[CategoryId]) AND ([Extent2].[CategoryId] = [Extent1].[Id]) WHERE N 'cj' = [Extent2].[Author] ) AS [Distinct1] |
下面分别来说说这四种方法:
第一种方法Any,更符合我们的查询习惯,也就是文章开始提到的问题的查询风格,只不过里面的Where应该换成Any
第二种方法Select,生成的SQL语句,跟我们自己写的SQL语句是一样的,这种方法以Post为查询主体,好处可以看看SQL语句优化方面的知识。
第三种和第四种都是SelectMany,虽然EF的查询写法不同,但生成的SQL语句完全相同, 当然SelectMany是以Category为查询主体。关于SelectMany的用法请参考MSDN。
补充(2014-5-11)
第五种方法,使用Contains
1
|
var list = ctx.Categories.Where(t => t.Posts.Select(s => s.Author).Contains( "cj" )); |
生成的SQL语句如下:
1
2
3
4
5
6
7
8
9
|
SELECT [Extent1].[Id] AS [Id], [Extent1].[ Name ] AS [ Name ] FROM [dbo].[Categories] AS [Extent1] WHERE EXISTS ( SELECT 1 AS [C1] FROM [dbo].[Posts] AS [Extent2] WHERE ([Extent1].[Id] = [Extent2].[CategoryId]) AND (N 'cj' = [Extent2].[Author]) ) |
这种方法和第一种方法Any生成的SQL语句是一样一样的。
EntityFramework嵌套查询的五种方法的更多相关文章
- Android之数据存储的五种方法
1.Android数据存储的五种方法 (1)SharedPreferences数据存储 详情介绍:http://www.cnblogs.com/zhangmiao14/p/6201900.html 优 ...
- 顽石系列:CSS实现垂直居中的五种方法
顽石系列:CSS实现垂直居中的五种方法 在开发过程中,我们可能沿用或者试探性地去使用某种方法实现元素居中,但是对各种居中方法的以及使用场景很不清晰.参考的内容链接大概如下: 行内元素:https:// ...
- 【SQL】Oracle分页查询的三种方法
[SQL]Oracle分页查询的三种方法 采用伪列 rownum 查询前10条记录 ? 1 2 3 4 5 6 7 8 9 10 11 [sql] select * from t_user t whe ...
- Java 字符串拼接 五种方法的性能比较分析 从执行100次到90万次
[请尊重原创版权,如需引用,请注明来源及地址] > 字符串拼接一般使用“+”,但是“+”不能满足大批量数据的处理,Java中有以下五种方法处理字符串拼接,各有优缺点,程序开发应选择合适的方法实现 ...
- js去掉字符串前后空格的五种方法
转载 :http://www.2cto.com/kf/201204/125943.html 第一种:循环检查替换[javascript]//供使用者调用 function trim(s){ ret ...
- 实现sticky footer的五种方法
2017-04-19 16:24:48 什么是sticky footer 如果页面内容不够长的时候,页脚块粘贴在视窗底部:如果内容足够长时,页脚块会被内容向下推送. 用position实现? 如果是用 ...
- linux 清空catalina.out日志 不需要重启tomcat(五种方法)【转】
1.重定向方法清空文件 [root@localhost logs]# du -h catalina.out 查看文件大小17M catalina.out[root@localhost logs] ...
- C#中得到程序当前工作目录和执行目录的五种方法
string str="";str += "\r\n" + System.Diagnostics.Process.GetCurrentProcess().Mai ...
- 【转】这五种方法前四种方法只支持IE浏览器,最后一个方法支持当前主流的浏览器(火狐,IE,Chrome,Opera,Safari)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
随机推荐
- [转]使用ant让Android自动打包的build.xml,自动生成签名的apk文件(支持android4.0以上的版本)
在android4.0以后的sdk里那个脚本就失效了,主要是因为 apkbuilder这个程序不见了: 人家sdk升级,我们的脚本也要跟上趟,修改一下喽. 上网一查,大家的文章还停留在我去年的脚本程度 ...
- 在Windows/Ubuntu下安装OpenGL环境(GLUT/freeglut)与跨平台编译(mingw/g++)
GLUT/freeglut 是什么? OpenGL 和它们有什么关系? OpenGL只是一个标准,它的实现一般自带在操作系统里,只要确保显卡驱动足够新就可以使用.如果需要在程序里直接使用OpenGL, ...
- 译:在C#中使用LINQ To SQL
译文出处:http://www.codeproject.com/Tips/871938/LINQ-To-SQL-Using-Csharp 今天在这个话题中,我给大家分享一个在c#编程中非常有趣和十分有 ...
- drupal7 Views Bulk Operations (VBO)
介绍 drupal通常用views制作列表,列表也应该能实现某些操作,例如删除.审批等,并且应该是批量进行的,VBO的存在就是为了实现views批量操作功能.事实上,drupal把操作统称为actio ...
- [Sql Server2008]树结构的递归算法
http://blog.csdn.net/tonyzhou2008/article/details/5100683 本文主要讲述三个内容: 1.如何创建hierarychyid的表,插入数据及基本递归 ...
- CCF推荐国际学术期刊
中国计算机学会推荐国际学术期刊 (计算机系统与高性能计算) 一.A类 序号 刊物简称 刊物全称 出版社 网址 1 TOCS ACM Transactions on Computer Systems A ...
- Ubuntu 14.04 载入 JWS 或 访问 jsp异常的解决方法
前段时间在Ubuntu 14.04中使用 Chrome登录 Webex准备面试的时候发现无法进入在线面试.搞笑的是前一天尝试进入 Webex的时候还一切正常,不过当时Webex的在线面试没有开始.等到 ...
- php高级面试题知识点(转载)
php高级面试题知识点大全 时间:2016-01-26 06:36:22来源:网络 导读:php高级面试题知识点大全,本套面试题内容包括php魔术方法.php单点登录.linux基本命令.前端开发技术 ...
- JavaScript进阶内容1:各种对象类型判断
该文章主要用来介绍JavaScript中常用的一些对象检测判断方法,整理资源来自书本和网络,如有错误或说明不详之处,望评论提出,本菜定提名感谢……(本文章知识比较基础,大牛请提些意见再绕道,三克油^_ ...
- Linux下查看tcp连接数及状态
netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’ TIME_WAIT 8947FIN_WAIT1 15FIN_W ...