LINQ TO SQL 中的join(转帖)
http://www.cnblogs.com/ASPNET2008/archive/2008/12/21/1358152.html
join对于喜欢写SQL的朋友来说还是比较实用,也比较容易接受的东西。在LINQ TO SQL中,写多表查询,同样可以写join,只是它有它自己的语法要求而已,语义都是一样的,下面我来讲下LINQ TO SQL中的join最基本的形式:都是最简单的,当然还有其它方面的内容,如:怎样加上过滤条件,如何分组,如何排序等等,为了单纯说join的用法,这里就简化下。
from c in Customers join p in Purchases on c.ID equals p.CustomerID select c.Name + " bought a " + p.Description
生成的SQL:
SELECT ([t0].[Name] + @p0) + [t1].[Description] AS [value] FROM [Customer] AS [t0] INNER JOIN [Purchase] AS [t1] ON ([t0].[ID]) = [t1].[CustomerID]
通过生成的SQL,我们可以非常清晰的看出,显示的使用了inner join,它的基本要求好下: 1:包含join和on关键字,如果只有join没有on,会报语法错误。
2:外键关联时,用的是关键字equals,而不能像SQL一样用等号。
3:必须显示调用要显示的字段。即要出现select 字段,否则会报错。
LINQ TO SQL与传统SQL的相同点:
1:join的用法,并不关心主表在前还是在后,最终的结果都是相同的。上面的查询我们也可以这样写。
from p in Purchases join c in Customers on p.CustomerID equals c.ID select c.Name + " bought a " + p.Description;
2:LINQ TO SQL同样支持两表以上的关联,
from c in Customers join p in Purchases on c.ID equals p.CustomerID // first join join pi in PurchaseItems on p.ID equals pi.PurchaseID // second join select new { c.Name, p.Description, pi.Detail }
LINQ TO SQL与传统SQL的不同点:
1:LINQ TO SQL中的join,如果带有into,可以提前对表进行过滤条件的操作,而不用等到两表进行迪卡尔积产生虚似表后再进行join on的条件过滤。
Code from c in Customers join p in Purchases.Where (p2 => p2.Price > 1000) on c.ID equals p.CustomerID into custPurchases where custPurchases.Any() select new { CustName = c.Name, custPurchases }
产生的SQL:
Code SELECT [t0].[Name] AS [CustName], [t1].[ID], [t1].[CustomerID], [t1].[Date], [t1].[Description], [t1].[Price], ( SELECT COUNT(*) FROM [Purchase] AS [t3] WHERE (([t0].[ID]) = [t3].[CustomerID]) AND ([t3].[Price] > @p0) ) AS [value] FROM [Customer] AS [t0] LEFT OUTER JOIN [Purchase] AS [t1] ON (([t0].[ID]) = [t1].[CustomerID]) AND ([t1].[Price] > @p0) WHERE EXISTS( SELECT NULL AS [EMPTY] FROM [Purchase] AS [t2] WHERE (([t0].[ID]) = [t2].[CustomerID]) AND ([t2].[Price] > @p0) ) ORDER BY [t0].[ID], [t1].[ID]
2:LINQ TO SQL包含一个groupjoin的概念,来看下MSDN对它的定义:
Queryable..::.GroupJoin 方法:基于键相等对两个序列的元素进行关联并对结果进行分组。这样情况一般都发生在一对多的情况,以主表的主键为分组对象,通过主表的主键来查询出子表的集合。
拿客人和消费记录表来说吧:一个客人会有多笔消费,我们要想得到所有客人的所有消费情况及客人姓名,即最外层的集合对象是所有客人信息,而客人的消费信息通过一个EntitySet集合来体现。在传统SQL中要想通过一个查询是做不到的,因为传统的SQL返回的只是一个具体的集合,具体记录中是不能再包含子记录的。而LINQ TO SQL则可以做到,可以通过主表记录的EntitySet属性来包含子表的集合。
var list = (from c in db.Customers join p in db.Purchases on c.ID equals p.CustomerID into custPurchases select new {custPurchases,c.Name}).ToList ();
效果图:如图一,
可以非常清楚的看出子表Puchase的内容以集合Puchase出现在最终的结果中,另外一列的内容是客户名。我们可以非常方便的取用户的某些信息。
//第一个用户的所有消费记录 List<Purchase> _list = list[0].custPurchases .ToList<Purchase >() ; //取第一个用户的第一条消费记录的价格 decimal dPrice = _list[0].Price;
可以看出LINQ模式对于开发效率还是有很大程度提高的,完全面向对象,逻辑性好,阅读性强。
对应的SQL:
SELECT [t1].[ID], [t1].[CustomerID], [t1].[Date], [t1].[Description], [t1].[Price], ( SELECT COUNT(*) FROM [Purchase] AS [t2] WHERE ([t0].[ID]) = [t2].[CustomerID] ) AS [value], [t0].[Name] FROM [Customer] AS [t0] LEFT OUTER JOIN [Purchase] AS [t1] ON ([t0].[ID]) = [t1].[CustomerID] ORDER BY [t0].[ID], [t1].[ID]
效果图:如图二,传统SQL看起来是一个完整的集合,它没有子对象的概念。
总结:上面的所有语句都可以用等效的拉姆达表态式来代替,只不过如果是像我一样的初学者,总觉的看拉姆达表达示特别别扭,用类似SQL的语句会容易接受些。join可以和上篇文章讲的selectMany来相互转换。要想join生成LEFT OUT JOIN,同样可以用DefaultIfEmpty()来实现,有兴趣的朋友可以试下。
LINQ TO SQL 中的join(转帖)的更多相关文章
- SQL中inner join、outer join和cross join的区别
对于SQL中inner join.outer join和cross join的区别简介:现有两张表,Table A 是左边的表.Table B 是右边的表.其各有四条记录,其中有两条记录name是相同 ...
- SQL中关于Join、Inner Join、Left Join、Right Join、Full Join、On、 Where区别
前言: 今天主要的内容是要讲解SQL中关于Join.Inner Join.Left Join.Right Join.Full Join.On. Where区别和用法,不用我说其实前面的这些基本SQL语 ...
- 【转载】SQL中inner join、outer join和cross join的区别
对于SQL中inner join.outer join和cross join的区别很多人不知道,我也是别人问起,才查找资料看了下,跟自己之前的认识差不多, 如果你使用join连表,缺陷的情况下是inn ...
- LINQ to SQL 中 Concat、Union、Intersect、Except 方法的使用
Ø 前言 LINQ to SQL 中需要对两个或多个数据集进行操作,比如:合并.取交集等,主要使用下面四个方法,这四个方法都是 System.Linq.IQueryable<out T> ...
- linq to sql中的自动缓存(对象跟踪)
linq to sql中,对于同一个DataContext上下文环境,根据表主键选择记录时(当然这里所指的“记录”会自动转成“对象”),如果该记录已经被select过,默认情况下会被自动缓存下来,下次 ...
- Linq to sql中使用DateDiff()
Linq to sql中使用DateDiff() 计算时间差的方法 第一种办法: from p in PurchaseLists where EntityFunctions.DiffDays(p.Cr ...
- Linq to sql中继承类映射转换问题
类型为的数据成员“Int32 VTOUID”不是类型的映射的一部分.该成员是否位于继承层次结构根节点的上方? 想躲开Linq to sql中问题限制可真是不容易: http://www.makaido ...
- sql中的join
首先准备数据 有以下数据,三张表:role(角色表).hero(英雄表).skill(技能表),我们以英雄联盟的数据做示例 一个hero对应一个role(我们这里暂定) 一个role可以对应多个her ...
- Linq To Sql中实现Left Join与Inner Join使用Linq语法与lambda表达式
当前有两个表,sgroup与sgroupuser,两者通过gKey关联,而sgroup表记录的是组,而sgroupuser记录是组中的用户,因此在sgroupuser中不一定有数据.需要使用Left ...
随机推荐
- 流媒体传输协议详解之---RTSP认证
from:http://blog.csdn.net/machh/article/details/52121648 Rtsp认证主要分为两种: 基本认证(basic authentication)和 ...
- 微信公众号平台开发(二)信息的分类.md
在上一篇博客中,我们只是简单地与微信服务器建立了连接,接下来就是从微信服务器中接收信息了.在SecurityController中,我定义了两个方法(get和post).Get方法是我们用来与微信服务 ...
- 小程序数组型图片自适应效果的实现(交流QQ群:604788754)
//本例代码如有问题,请加群,下载今日日期文件,测试.(如对本例有疑问,也可加群咨询群主) WXML: <view class="imgbox"> <block ...
- zoj2112&&bzoj1901
题解: 可修改的主席树 一开始,我就按照最暴力的方法,空间nlognlogn 然后zju上面过不了,bzoj没有权限号 然后,参考了往上的论文,发现可以把初始的主席树先建好 然后,每次只需要维护修改的 ...
- 第三视角团队:项目UML设计(团队)
项目UML设计(团队) 团队信息 团队名:第三视角 各成员学号及姓名 姓名 学号 博客链接 张扬(组长) 031602345 http://www.cnblogs.com/sxZhangYang/p/ ...
- MyEclipse 2017 CI 9 发布(附下载)
挑战全年最低价!MyEclipse线上狂欢继续!火热开启中>> 在进入年底之时,2017 CI 9是我们最大的版本发布之一.在新版本中,我们添加了对Angular 5和TypeScript ...
- 踢掉某个li
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- HDU 4862
http://acm.hdu.edu.cn/showproblem.php?pid=4862 #include <iostream> #include <cstdio> #in ...
- 如何更改/删除magento首页产品/广告图片等模块信息
如何更改/删除magento首页产品/广告图片等模块信息,如果只是修改一些简单的地方,例如已经存在 的左右栏目里面的图片内容等,是很简单的,直接在后台就可以修改的,具体如下: 如何删除magento首 ...
- Texas Instruments matrix-gui-2.0 hacking -- json.txt
{ "main_menu": { "apps": [ { "Name":"Profiling", ", &qu ...