zoukankan      html  css  js  c++  java
  • LINQ TO SQL 中的join

    http://www.cnblogs.com/ASPNET2008/archive/2008/12/21/1358152.html

    LINQ TO SQL 中的join

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

    « 博主前一篇:LINQ TO SQL中的selectMany
    » 博主后一篇:LINQ TO SQL 中的group


    注:
       文中参考nutshell示例

     « 博主前一篇:LINQ TO SQL中的selectMany
    » 博主后一篇:LINQ TO SQL 中的group

  • 相关阅读:
    Python Excel 合并 去重
    前端 导出为Excel 数据源为table表格 table中的字段7-1变成了7月1号解决
    SpreadJS 基本信息
    Python 模拟向四面八方拖动
    Python 淘宝联盟-佣金设置 批量设置佣金和服务费
    Python 模拟鼠标滚轮 滚动页面
    评审恩仇录——我为什么愿意执行代码评审
    浅谈专有云MQ存储空间的清理机制
    三只松鼠:阿里云数据中台基座上的多渠道、多业态生长
    谈AK管理之基础篇
  • 原文地址:https://www.cnblogs.com/guyuehuanhuan/p/2376875.html
Copyright © 2011-2022 走看看