例如,可以将产品表与产品类别表相联接,得到产品名称和与其相对应的类别名称

db.Products
.Join
(
db.Categories,
p => p.CategoryID,
c => c.CategoryID,
(p, c) => new {p,c.CategoryName}
)
.Where(p => p.CategoryID == );

这个Join对应SQL里的inner Join, 这个很容易理解. 上面代码里红色的c的类型是Category

如果我要达到SQL里Left Join的效果, 该怎么写呢? 想当然的以为,把Join改成GroupJoin,

db.Products
.GroupJoin
(
db.Categories,
p => p.CategoryID,
c => c.CategoryID,
(p, cs) => new {p,cs.FirstOrDefault().CategoryName}
)
.Where(p => p.CategoryID == );

上面代码里红色的cs的类型是IEnumerable<Category>, 你用FirstOrDefault()只是拿到一个目录,万一Product Left join是有多个目录呢?

所以要用.SelectMany把IEnumerable<Category> 把里面的每一个元素做投影.

要注意加上DefaultIfEmtyp() 才是Left join, 假如没有加这个,还是Inner Join

db.Products
.GroupJoin(db.Categories,
(Product p) => p.CategoryId,
(Category c) => c.CategoryId,
(prod, cs) => new { prod, cs }) // cs is IEnumerable<Category>
.SelectMany(prodCats => prodCats.cs.DefaultIfEmpty(), (prodCats, c) =>
new
{
prodCats.prod
categoryName = c.CategoryName
});

用LinQ query表达式 对应的写法是

            var qry =
from p in db.Products
join c in db.Categories on p.CategoryId equals c.CategoryId
into g from pc in g.DefaultIfEmpty()
select new {
prodId = p.ProdId,
prodCode = p.ProdCode,
prodName = p.ProdName,
categoryName = g.FirstOrDefault().CategoryName
};

如果我只用DefaultIfEmpty(),不用GroupJoin,这样写能达到这个效果吗?

            var qry = db.Products.SelectMany
(
p => db.Categories.Where(c => c.CategoryId == p.CategoryId).DefaultIfEmpty(),
(p, c) => new
{
p.ProdId,
p.ProdCode,
p.ProdName,
c.CategoryName
}
);

这样写,如果数据量大,性能会很差. 因为它会把Products和Categories都Load到内存里,再Match, 而不是用SQL Left Join

参考文章:

https://stackoverflow.com/questions/584820/how-do-you-perform-a-left-outer-join-using-linq-extension-methods

http://linqsamples.com/linq-to-objects/join/GroupJoin-linq

https://docs.microsoft.com/en-us/dotnet/csharp/linq/perform-left-outer-joins

Lamda 表达式里的Join和GroupJoin的区别, 如何实现SQL的Left Join效果的更多相关文章

  1. [C#]使用Join与GroupJoin将两个集合进行关联与分组

    本文为原创文章.源代码为原创代码,如转载/复制,请在网页/代码处明显位置标明原文名称.作者及网址,谢谢! 本文使用的开发环境是VS2017及dotNet4.0,写此随笔的目的是给自己及新开发人员作为参 ...

  2. C#中使用Join与GroupJoin将两个集合进行关联与分组

    转自:https://www.cnblogs.com/cncc/p/7985843.html 对于Join的用法说明如下: 语法: public static IEnumerable<TResu ...

  3. LINQ的左连接、右连接、内连接和Lamda表达式实现Left join

    1.左连接: var LeftJoin = from t1 in l1join t2 in l2on t1.ID equals t2.ID into Joinedt12from t3 in Joine ...

  4. SQL、Linq、lamda表达式 同一功能不同写法

    一.SQL.Linq.lamda表达式 同一功能不同写法 SQL LINQ Lambda SELECT * FROM HumanResources.Employee from e in Employe ...

  5. 解读ASP.NET 5 & MVC6系列(12):基于Lamda表达式的强类型Routing实现

    前面的深入理解Routing章节,我们讲到了在MVC中,除了使用默认的ASP.NET 5的路由注册方式,还可以使用基于Attribute的特性(Route和HttpXXX系列方法)来定义.本章,我们将 ...

  6. Linq和Lamda表达式的简单处理方式

    一 什么是LINQ? LINQ即Language Integrated Query(语言集成查询),LINQ是集成到C#和Visual Basic.NET这些语言中用于提供查询数据能力的一个新特性. ...

  7. python 内置函数 lamda表达式。 open 文件方法

    lamda 表达式 lambda表达式 学习条件运算时,对于简单的 if else 语句,可以使用三元运算来表示,即: 普通的条件语句 if 1 == 1: name = 'kaixin' else: ...

  8. LINQ查询操作符之Select、Where、OrderBy、OrderByDescending、GroupBy、Join、GroupJoin及其对应的查询语法

    介绍    ·Select - Select选择:延迟    ·Where - Where查询:延迟    ·OrderBy - 按指定表达式对集合正序排序:延迟    ·OrderByDescend ...

  9. 让操作javascript对象数组像.net lamda表达式一样

    让操作javascript对象数组像.net lamda表达式一样 随着web应用程序的富客户端化.ajax的广泛使用及复杂的前端业务逻辑.对js对象数组.json数组的各种操作越来越多.越来越复杂. ...

随机推荐

  1. 转一个集成速锐的ss 回头试试 补充加速一、Vultr安装锐速

    https://liyuans.com/archives/ssr-serverspeeder-onekey.html Debian/Ubuntu 系统 ShadowsocksR 一键安装脚本 (集成锐 ...

  2. Java生成指定长度的随机数

    char[] str = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', ' ...

  3. PHP直接将文件流转换为字符串

    有时候不需要图片直接输出到浏览器,需要如下处理! 输出到浏览器 $qrCode = new QrCode(); $qrCode ->setText('Life is too short to b ...

  4. HAProxy用法详解

    一.HAProxy简介 (1)HAProxy 是一款提供高可用性.负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,支持虚拟主机,它是免费.快速并且可靠的一种解决方案. HAProx ...

  5. 滑动验证 和滑动图片验证JS

    滑动验证 先放效果图 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  6. C语言之网络编程(服务器和客户端)

    Linux网络编程 1. 套接字:源IP地址和目的IP地址以及源端口号和目的端口号的组合称为套接字.其用于标识客户端请求的服务器和服务. 常用的TCP/IP协议的3种套接字类型如下所示. (1)流套接 ...

  7. 虹软人脸识别SDK(java+linux/window)

    虹软官网:http://www.arcsoft.com.cn/ 登录后要实名认证才可以使用sdk. 下图这两个是我选择的,window版本地开发测试,linux版是生产环境使用. 1. 保存激活码,下 ...

  8. 学习笔记54—均方误差(MSE)和均方根误差(RMSE)和平均绝对误差(MAE)

    https://blog.csdn.net/reallocing1/article/details/56292877 MSE: Mean Squared Error  均方误差是指参数估计值与参数真值 ...

  9. Python 数字(Number)

    Python 数字(Number) Python 数字数据类型用于存储数值. 数据类型是不允许改变的,这就意味着如果改变数字数据类型的值,将重新分配内存空间. 以下实例在变量赋值时 Number 对象 ...

  10. 第 3 章 镜像 - 020 - 搭建本地 Registry

    Docker Hub 虽然非常方便,但还是有些限制,比如: 需要 internet 连接,而且下载和上传速度慢. 上传到 Docker Hub 的镜像任何人都能够访问,虽然可以用私有 reposito ...