zoukankan      html  css  js  c++  java
  • 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

           产生的SQL:

    Code

       

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

  • 相关阅读:
    C++设计模式之-代理模式
    C++实现设计模式之-装饰模式
    C++实现设计模式之 —策略与简单工程结合
    C++笔记(5)——浮点数的比较
    PAT 1001 A+B Format (20 point(s))
    LeetCode——28. Implement strStr()
    LeetCode——3. Longest Substring Without Repeating Characters
    LeetCode——160 Intersection of Two Linked Lists
    LeetCode——142 设计链表2
    LeetCode——141 设计链表
  • 原文地址:https://www.cnblogs.com/xihong2014/p/4161949.html
Copyright © 2011-2022 走看看