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的用法,这里就简化下。

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->from c in Customers join p in Purchases on c.ID equals p.CustomerID select c.Name + " bought a " + p.Description

生成的SQL:

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->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的用法,并不关心主表在前还是在后,最终的结果都是相同的。上面的查询我们也可以这样写。

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->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同样支持两表以上的关联,

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->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

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->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

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->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属性来包含子表的集合。

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> 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出现在最终的结果中,另外一列的内容是客户名。我们可以非常方便的取用户的某些信息。

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->//第一个用户的所有消费记录             List<Purchase> _list = list[0].custPurchases .ToList<Purchase >() ;             //取第一个用户的第一条消费记录的价格             decimal dPrice = _list[0].Price;

可以看出LINQ模式对于开发效率还是有很大程度提高的,完全面向对象,逻辑性好,阅读性强。

对应的SQL:

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->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()来实现,有兴趣的朋友可以试下。

时间: 2024-10-18 09:10:22

LINQ TO SQL 中的join(转帖)的相关文章

LINQ to SQL 中 Concat、Union、Intersect、Except 方法的使用

?  前言 LINQ to SQL 中需要对两个或多个数据集进行操作,比如:合并.取交集等,主要使用下面四个方法,这四个方法都是 System.Linq.IQueryable<out T> 接口的扩展方法,并且都是延迟加载方法,下面是使用的简单示例. ?  示例数据,数据表:Subject(科目表).Score(成绩表) 1.   Concat() 方法 1)   方法声明 public static IQueryable<TSource> Concat<TSource>

30秒懂SQL中的join

30秒懂SQL中的join 注:本文仅仅是本人在网上看到的比较好的文章,为了以后复习方便,就文章 完全复制下来.原文地址如下:http://www.habadog.com/ 预先生成两张测试表,并插入一下测试数据: create table t1(id int, name char(10), primary key (id)); create table t2(id int, score int, primary key (id)); insert into t1 values(1, “lucy

Linq To Sql 中未将对象引用设置到对象的实例

我们在DAL对方法进行封装 public void Delete(T entity) { db.GetTable<T>().DeleteOnSubmit(entity); db.SubmitChanges(); } 对stuInfo进行删除 public void Delete(StuInfo stuInfo) { db.Delete(stuInfo); } 这条语句是之前已经插入过的 StuInfo stuinfo = new StuInfo { StuAge = 18, StuNo = &

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语法各位攻城狮基本上都用过.但是往往我们可能用的比较多的也就是左右连接和内连接了,而且对于许多初学者而言不知道什么时候该用哪种语法进行查询,并且对于左右,或者内连接查询的时候关于ON 和Where 的作用也是模糊不清的,说不出其中的一个大概的差别,因此接下来请容我把它们好好描述一遍. 数据库(MS S

Linq To Sql中实现Left Join与Inner Join使用Linq语法与lambda表达式

当前有两个表,sgroup与sgroupuser,两者通过gKey关联,而sgroup表记录的是组,而sgroupuser记录是组中的用户,因此在sgroupuser中不一定有数据.需要使用Left Join获取数据: Linq语法如下: var sg = (from g in dc.sgroup join gu in dc.sgroupuser on g.gKey equals gu.gKey into l from lgu in l.DefaultIfEmpty() select new {

SQL中的JOIN语法详解

参考以下两篇博客: 第一个是 sql语法:inner join on, left join on, right join on详细使用方法 讲了 inner join, left join, right join的意义和用法. 第二个是 SQL中的left outer join,inner join,right outer join用法详解 讲了关系运算背后的数学原理,以及提到了更多类型的连接操作: inner join- 笛卡尔乘积再选取, left outer join, right out

Access SQL中Left Join、Right Join和Inner Join的使用

1.表结构 表A                                     表B 2.Left Join 示例:2.1 Select * From A left join B on A.aid = B.bid; left join是以A表的记录为基础的,A可以看成左表,B可以看成右表,left join是以左表为准的. 换句话说,左表A的记录将会全部表示出来,而右表B只会显示符合搜索条件的记录(例子中为: A.aid = B.bid),B表记录不足的地方均为NULL. A表所有记录

也记一次性能优化:LINQ to SQL中Contains方法的优化

距离上一篇博文更新已经两个月过去了.在此,先表一表这两个月干了些啥: 世界那么大,我也想去看看.四月份的时候,我入职了上海的一家电商公司,职位是.NET高级开发工程师.工作一个月,最大的感受是比以前小城市匆忙了许多,工作压力大了许多,开发方式更加的正规,不过各种流程也更加的繁杂细琐.在写代码的时候,一定要严谨细心,该验证参数合法性的时候验参,该抛异常的时候抛异常,该写日志的时候写日志,因为一个不小心而报黄页或者主流程无法顺利进行下去,是很没面子的事情.另外,我也更加关注代码的性能问题,开发环境和

linq to sql中修改连接字符串

如果在类库中在添加linq to sql并连接完数据库服务器后会自动生成settings.settings文件,app.config文件用于存储连接字符串(图一) 如要修改连接字符串要修改哪个还是要全部修改呢?经过我研究发现最简单只需要修改dbml一个文件即可,因为三者是关联的,dbml修改后其他两个文件会相应的修改,但是这是有顺序的:dbml.settings.settings和app.config,修改其中一个连接字符串会将之后文件中的连接字符串同步.否则逆向修改会麻烦一些比如修改了app.