LINQ学习

本文深入探讨了LINQ查询的不同方面,包括如何使用SelectMany表达一对多的关系,以及如何实现SQL中的cross join、inner join和LEFT OUTER JOIN等经典联接方式。此外,还介绍了如何在查询中应用过滤条件。

 

  // var list = (from d in _DeliveryRepository.Query()
            
//             from s in d.StorageList
            
//             from f in s.FreightRelationList
            
//             where f.Departmetnid == departmentcode && d.Code == delivery
            
//             select s).ToList();

            
// var list1 = (from s in _storageRepository.Query()
            
//                  .FetchMany(p => p.DeliveryList).FetchMany(p => p.FreightRelationList)
            
//              from d in s.DeliveryList
            
//              from f in s.FreightRelationList
            
//              where f.Departmetnid == departmentcode && d.Code == delivery
            
//              select s).ToList();

             var list2 = _storageRepository.Query()
                             .FetchMany(p => p.DeliveryList).FetchMany(p => p.FreightRelationList)
                             .Where(p => p.DeliveryList.Any(a => a.Code == delivery) &&                                                    p.FreightRelationList.Any(a => a.Departmetnid == departmentcode)).ToList();
             return list2;

 

 

 

 

list,set的转换

List list = new ArrayList(set);
Set set = new HashSet(list);

  

 

 List<t_ExpoEntity> t_ExpoEntityList = new List<t_ExpoEntity>();
            dd.Author = "11";
            t_ExpoEntityList.Add(dd);
            dd = new t_ExpoEntity();
            dd.Author = "22";
            t_ExpoEntityList.Add(dd);

            List<t_ExpoEntity> t_ExpoEntityList2 = t_ExpoEntityList.FindAll(
                delegate(t_ExpoEntity temp)
                {
                    return temp.Author == "11";
                }
                );

 

 

 

LINQ TO SQL中的selectMany

 

首先看SelectMany的定义:

     Queryable中的SelectMany 方法:将序列的每个元素投影到一个 IEnumerable<(Of <(T>)>) 并将结果序列组合为一个 IQueryable<(Of <(T>)>) 类型的序列。(引用MSDN)

     在用LINQ TO SQL 来写查询语句时,有一个selectMany的语句,它标示着一对多的关系,这篇文章我想说下在LINQ TO SQL中几种可以等同selectMany的用法。

      系统转换成selectMany的条件:
          1:语句中不包含join ,into;
          2:需要2个以上的from:下面以两个表为例:如第一个表from c in 表1
             1):如果from的对象均用表名,(from c in 表2),则会转换成cross join;
             2):如果第二个表名以第一个表的子表形式出现,即类似c.表2,这又分两种情况,
                 1>:from o in c.表2,此时会形成inner join
                 2>:from p in c.表2.DefaultIfEmpty(),此时会形成LEFT OUT JOIN

     文中例子表结构说明:Customer表和Purchase表,通过ID与CustomerID建立关联。

复制代码
CREATE TABLE [dbo].[Customer](
    [ID] [
int ] NOT NULL,
    [Name] [nvarchar](
30 ) )

CREATE TABLE [dbo].[Purchase](
    [ID] [
int ] NOT NULL,
    [CustomerID] [
int ] NULL,
    [Date] [datetime] NOT NULL,
    [Description] [varchar](
30 ) )
复制代码


      我们来实现SQL中的三种非常经典的联接方式。

      第一:cross join,它的结果集是所有表的迪卡尔积。

// cross join
    from c  in  Customers
    from o 
in  Purchases
    select o

 

     在LINQ TO SQL中,下面的from都指定为表名的话,就会生成下面的语句:

SELECT [t1].[ID], [t1].[CustomerID], [t1].[Date], [t1].[Description], [t1].[Price]
FROM [Customer] AS [t0], [Purchase] AS [t1]


     第二:inner join。

// inner join
    from c  in  Customers
    from o 
in  c.Purchases
    select o

    

     生成的SQL如下:

SELECT [t1].[ID], [t1].[CustomerID], [t1].[Date], [t1].[Description], [t1].[Price]
FROM [Customer] AS [t0], [Purchase] AS [t1]
WHERE [t1].[CustomerID] 
=  [t0].[ID]

 

     虽然没有显示的用inner join,但和它的功能是一样的.它的写法和上面的cross join看起来特别像,唯一的区别就在于cross join时,直接用了表名Purchases,而inner join用的时候变成了c.Pruchasex,即形成了一对多的情况。

     第三:   LEFT OUTER JOIN

from c  in  Customers
    from p 
in  c.Purchases.DefaultIfEmpty()
    select 
new  { c.Name, p.Description, Price  =  ( decimal ? ) p.Price }

 

    生成的SQL如下:

SELECT [t0].[Name], [t1].[Description] AS [Description], [t1].[Price] AS [Price]
FROM [Customer] AS [t0]
LEFT OUTER JOIN [Purchase] AS [t1] ON [t1].[CustomerID] 
=  [t0].[ID]

 

    left outer join实际上是在inner join的基础上加了一个条件,利用DefaultIfEmpty(),当记录不匹配时,返回null
我们对上在的查询增加一个过滤条件。

复制代码
from c  in  Customers
from p 
in  c.Purchases.Where (p  =>  p.Price  >   1000 ).DefaultIfEmpty()
select 
new
{
    c.Name,
    p.Description,
    Price 
=  ( decimal ? ) p.Price
}
复制代码

 

     对应的SQL:

SELECT [t0].[Name], [t1].[Description] AS [Description], [t1].[Price] AS [Price]
FROM [Customer] AS [t0]
LEFT OUTER JOIN [Purchase] AS [t1] ON ([t1].[Price] 
>  @p0) AND ([t1].[CustomerID]  =  [t0].[ID])

    

     此时上面的语句还是标准的LEFT OUT JOIN,如果我们改变下条件的位置呢?

复制代码
from c  in  Customers
from p 
in  c.Purchases.DefaultIfEmpty()
where  p.Price > 1000
select 
new
{
    c.Name,
    p.Description,
    Price 
=  ( decimal ? ) p.Price
}
复制代码

   

       对应的SQL:

复制代码
SELECT [t0].[Name], [t1].[Description] AS [Description], [t1].[Price] AS [Price]
FROM [Customer] AS [t0]
LEFT OUTER JOIN [Purchase] AS [t1] ON [t1].[CustomerID] 
=  [t0].[ID]
WHERE [t1].[Price] 
>  @p0
复制代码

 

       条件改变位置后并没有改变join的本质,还是LEFT OUT JOIN,只不过查询的结果不一样了,从结果集上看,后面一种的效果和inner join的结果一样。

       总结:上面的查询语句也可以用显示的join来查询,个人更喜欢用显示的join,因为相比较SQL更接近些,看起来要亲近些。在下篇文章中,我会总结显示用join查询的用法,其实最终的显示结果都一样,只是写法不同。

 

 

 List<Teacher> teachers = new List<Teacher>
            {
               
new Teacher("a",new List<Student>{ new Student(100),new Student(90),new Student(30) }),
               
new Teacher("b",new List<Student>{ new Student(100),new Student(90),new Student(60) }),
               
new Teacher("c",new List<Student>{ new Student(100),new Student(90),new Student(40) }),
               
new Teacher("d",new List<Student>{ new Student(100),new Student(90),new Student(60) }),
               
new Teacher("e",new List<Student>{ new Student(100),new Student(90),new Student(50) }),
               
new Teacher("f",new List<Student>{ new Student(100),new Student(90),new Student(60) }),
               
new Teacher("g",new List<Student>{ new Student(100),new Student(90),new Student(60) })
            };

 

  var list1 = from t in teachers
                       
from s in t.Students
                       
where s.Score < 60
                        select s;

 

var list2 = teachers.SelectMany(t => t.Students).Where(s => s.Score < 60);

 

 var list3 = teachers.SelectMany(
                t
=> t.Students,
                (t, s)
=> new { t.Name, s.Score })
                .Where(n
=> n.Score < 60);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值