c# LINQ操作集合

linq写法:

1.查询表达式

2.点标记法

 

LINQ包括五个部分:

 

LINQ to Objects:用于处理数组和集合
LINQ to Entities:在通过Entity Framework技术访问数据库时使用
LINQ to SQL:MS SQL Server中的数据访问技术
LINQ to XML:在处理XML文件时使用 LINQ to DataSet:在使用DataSet对象时使用 Parallel
LINQ(PLINQ):用于执行并行查询
这里介绍LINQ to Objects:用于处理数组和集合的操作。

1.2 LINQ常用关键字
关键字 含义
from 指定数据源和范围变量
where 根据布尔表达式(由逻辑与 或 等组成)从数据源中筛选元素
select 指定查询结果中的元素所具有的类型或表现形式
group 对对查询结果按照键值进行分组
into 提供一个标示符,它可以充当对 join group 或 select 子句结果的引用
orderby 对查询出的元素进行排序
join 按照两个指定匹配条件来联接俩个数据源
let 产生一个用于查询表达式中子表达式查询结果的范围变量

 

 

 

 

 

1.简单的linq语法,对比sql

复制代码
            //1
            var ss = from r in db.Am_recProScheme
                     select r;
            //2
            var ss1 = db.Am_recProScheme;
            //3
            string sssql = "select * from Am_recProScheme";
复制代码

2.带where的查询

复制代码
            //1
            var ss = from r in db.Am_recProScheme
                     where r.rpId > 10
                     select r;
            //2
            var ss1 = db.Am_recProScheme.Where(p => p.rpId > 10);
            //3
            string sssql = "select * from Am_recProScheme where rpid>10";
复制代码

3.简单的函数计算(count,min,max,sum)

复制代码
            //1
            ////获取最大的rpId
            //var ss = (from r in db.Am_recProScheme
            //          select r).Max(p => p.rpId);
            ////获取最小的rpId
            //var ss = (from r in db.Am_recProScheme
            //          select r).Min(p => p.rpId);
            //获取结果集的总数
            //var ss = (from r in db.Am_recProScheme                  
            //         select r).Count();
            //获取rpId的和
            var ss = (from r in db.Am_recProScheme
                      select r).Sum(p => p.rpId);


            //2
            //var ss1 = db.Am_recProScheme.Max(p=>p.rpId);
            //var ss1 = db.Am_recProScheme.Min(p => p.rpId);
            //var ss1 = db.Am_recProScheme.Count() ;
            var ss1 = db.Am_recProScheme.Sum(p => p.rpId);
            Response.Write(ss);

            //3
            string sssql = "select max(rpId) from Am_recProScheme";
                   sssql = "select min(rpId) from Am_recProScheme";
                   sssql = "select count(1) from Am_recProScheme";
                   sssql = "select sum(rpId) from Am_recProScheme";
复制代码

4.排序order by desc/asc

复制代码
            var ss = from r in db.Am_recProScheme
                     where r.rpId > 10
                     orderby r.rpId descending  //倒序
                     //  orderby r.rpId ascending   //正序
                     select r;

            //正序
            var ss1 = db.Am_recProScheme.OrderBy(p => p.rpId).Where(p => p.rpId > 10).ToList();
            //倒序
            var ss2 = db.Am_recProScheme.OrderByDescending(p => p.rpId).Where(p => p.rpId > 10).ToList();

            string sssql = "select * from Am_recProScheme where rpid>10 order by rpId [desc|asc]";
复制代码

5.top(1)

复制代码
            //如果取最后一个可以按倒叙排列再取值
            var ss = (from r in db.Am_recProScheme                     
                      select r).FirstOrDefault();

            //()linq to ef 好像不支持 Last() 
            var ss1 = db.Am_recProScheme.FirstOrDefault();
            //var ss1 = db.Am_recProScheme.First();          

            string sssql = "select top(1) * from Am_recProScheme";
复制代码

6.跳过前面多少条数据取余下的数据

复制代码
            //1
            var ss = (from r in db.Am_recProScheme
                      orderby r.rpId descending
                      select r).Skip(10); //跳过前10条数据,取10条之后的所有数据   
            //2  
            var ss1 = db.Am_recProScheme.OrderByDescending(p => p.rpId).Skip(10).ToList();
            //3
            string sssql = "select * from  (select ROW_NUMBER()over(order by rpId desc) as rowNum, * from [Am_recProScheme]) as t where rowNum>10";
复制代码

7.分页数据查询

复制代码
            //1
            var ss = (from r in db.Am_recProScheme
                      where r.rpId > 10
                      orderby r.rpId descending
                      select r).Skip(10).Take(10); //取第11条到第20条数据                   

            //2 Take(10): 数据从开始获取,获取指定数量(10)的连续数据
            var ss1 = db.Am_recProScheme.OrderByDescending(p => p.rpId).Where(p => p.rpId > 10).Skip(10).Take(10).ToList();
            //3
            string sssql = "select * from  (select ROW_NUMBER()over(order by rpId desc) as rowNum, * from [Am_recProScheme]) as t where rowNum>10 and rowNum<=20";
复制代码

8.包含,类似like '%%'

复制代码
            //1
            var ss = from r in db.Am_recProScheme
                     where r.SortsText.Contains("张")
                     select r;
            //2
            var ss1 = db.Am_recProScheme.Where(p => p.SortsText.Contains("张")).ToList();
            //3
            string sssql = "select * from Am_recProScheme where SortsText like '%张%'";
复制代码

9.分组group by

复制代码
            //1
            var ss = from r in db.Am_recProScheme
                     orderby r.rpId descending
                     group r by r.recType into n
                     select new
                     {
                         n.Key,  //这个Key是recType
                         rpId = n.Sum(r => r.rpId), //组内rpId之和
                         MaxRpId = n.Max(r => r.rpId),//组内最大rpId
                         MinRpId = n.Min(r => r.rpId), //组内最小rpId
                     };
            foreach (var t in ss)
            {
                Response.Write(t.Key + "--" + t.rpId + "--" + t.MaxRpId + "--" + t.MinRpId);
            }
            //2
            var ss1 = from r in db.Am_recProScheme
                     orderby r.rpId descending
                     group r by r.recType into n
                     select n;
            foreach (var t in ss1)
            {
                Response.Write(t.Key + "--" + t.Min(p => p.rpId));
            }
            //3
            var ss2 = db.Am_recProScheme.GroupBy(p => p.recType);
            foreach (var t in ss2)
            {
                Response.Write(t.Key + "--" + t.Min(p => p.rpId));
            }
            //4
            string sssql = "select recType,min(rpId),max(rpId),sum(rpId) from Am_recProScheme group by recType";


//多字段

var result = (from item in data
group item by new { item.Name, item.Type } into items
select new
{
    items.Key.Name,
    items.Key.Type,
    Cnt = items.Count()
}).ToList();


var s = data.GroupBy(p => new { p.Type, p.Name }).Select(p=>new {
          p.Key.Type,
          p.Key.Name,
          cnt=p.Count()
}).ToList();


复制代码

10.连接查询 

复制代码
            //1
            var ss = from r in db.Am_recProScheme
                     join w in db.Am_Test_Result on r.rpId equals w.rsId    //on是条件
                     orderby r.rpId descending
                     select r;
            //2
            var ss1 = db.Am_recProScheme.Join(db.Am_Test_Result, p => p.rpId, r => r.rsId, (p, r) => p).OrderByDescending(p => p.rpId).ToList();
            //3
            string sssql = "select r.* from  [Am_recProScheme] as r inner join [dbo].[Am_Test_Result] as t on r.[rpId] = t.[rsId] order by r.[rpId] desc";
复制代码

11.sql中的In

复制代码
            //1
            var ss = from p in db.Am_recProScheme
                              where (new int?[] { 24, 25,26 }).Contains(p.rpId)
                              select p;
            foreach (var p in ss)
            {
                Response.Write(p.Sorts);
            }
            //
            string st = "select * from Am_recProScheme where rpId in(24,25,26)";
复制代码

 

二:LINQ

1.查询操作符

(1)源起

.net的设计者在类库中定义了一系列的扩展方法,来方便用户操作集合对象,这些扩展方法构成了LINQ的查询操作符

(2)使用

这一系列的扩展方法,比如:Where,Max,Select,Sum,Any,Average,All,Concat等,都是针对IEnumerable的对象进行扩展的,也就是说,只要实现了IEnumerable接口,就可以使用这些扩展方法,来看看这段代码:

    List<int> arr = new List<int>() { 1, 2, 3, 4, 5, 6, 7 };
    var result = arr.Where(a => { return a > 3; }).Sum();
    Console.WriteLine(result);
    Console.ReadKey();

这段代码中,用到了两个扩展方法。

1、Where扩展方法,需要传入一个Func<int,bool>类型的泛型委托,这个泛型委托,需要一个int类型的输入参数和一个布尔类型的返回值,我们直接把a => { return a > 3; }这个lambda表达式传递给了Where方法,a就是int类型的输入参数,返回a是否大于3的结果。
2、Sum扩展方法计算了Where扩展方法返回的集合的和。

(3)好处

上面的代码中
arr.Where(a => { return a > 3; }).Sum();
这一句完全可以写成如下代码:
(from v in arr where v > 3 select v).Sum();
而且两句代码的执行细节是完全一样的,大家可以看到,第二句代码更符合语义,更容易读懂,第二句代码中的where,就是我们要说的查询操作符。

(4)标准查询操作符说明

  1. 过滤
    Where
    用法:arr.Where(a => { return a > 3; })
    说明:找到集合中满足指定条件的元素,
    OfType
    用法:arr.OfType<int>()
    说明:根据指定类型,筛选集合中的元素
  2. 投影
    Select
    用法:arr.Select<int, string>(a => a.ToString());
    说明:将集合中的每个元素投影的新集合中。上例中:新集合是一个IEnumerable<String>的集合
    SelectMany
    用法:arr.SelectMany<int, string>(a => { return new List<string>() { "a", a.ToString() }; });
    说明:将序列的每个元素投影到一个序列中,最终把所有的序列合并
  3. 还有很多查询操作符,请翻MSDN,以后有时间我将另起一篇文章把这些操作符写全。

2.查询表达式

(1)源起

上面我们已经提到,使用查询操作符表示的扩张方法来操作集合,虽然已经很方便了,但在可读性和代码的语义来考虑,仍有不足,于是就产生了查询表达式的写法。虽然这很像SQL语句,但他们却有着本质的不同。

(2)用法

from v in arr where v > 3 select v这就是一个非常简单的查询表达式

(3)说明:

先看一段伪代码:

  from [type] id in source
 [join [type] id in source on expr equals expr [into subGroup]]
 [from [type] id in source | let id = expr | where condition]
 [orderby ordering,ordering,ordering...]
 select expr | group expr by key
 [into id query]
  1. 第一行的解释:type是可选的,id是集合中的一项,source是一个集合,如果集合中的类型与type指定的类型不同则导致强制转化
  2. 第二行的解释:一个查询表达式中可以有0个或多个join子句,这里的source可以不等于第一句中的source,expr可以是一个表达式[into subGroup] subGroup是一个中间变量,它继承自IGrouping,代表一个分组,也就是说“一对多”里的“多”,可以通过这个变量得到这一组包含的对象个数,以及这一组对象的键,比如:
    from c in db.Customers
 join o in db.Orders on c.CustomerID
 equals o.CustomerID into orders
 select new
 {
    c.ContactName,
    OrderCount = orders.Count()
 };
  1. 第三行的解释:一个查询表达式中可以有1个或多个from子句,一个查询表达式中可以有0个或多个let子句,let子句可以创建一个临时变量,比如:
     from u in users
 let number = Int32.Parse(u.Username.Substring(u.Username.Length - 1))
 where u.ID < 9 && number % 2 == 0
 select u

一个查询表达式中可以有0个或多个where子句,where子句可以指定查询条件

  1. 第四行的解释:一个查询表达式可以有0个或多个排序方式,每个排序方式以逗号分割
  2. 第五行的解释:一个查询表达式必须以select或者group by结束,select后跟要检索的内容,group by 是对检索的内容进行分组,比如:
     from p in db.Products
   group p by p.CategoryID into g  
 select new {  g.Key, NumProducts = g.Count()}; 
  1. 第六行的解释:最后一个into子句起到的作用是将前面语句的结果作为后面语句操作的数据源,比如:
     from p in db.Employees
  select new
  {
      LastName = p.LastName,
      TitleOfCourtesy = p.TitleOfCourtesy
  } into EmployeesList
  orderby EmployeesList.TitleOfCourtesy ascending
  select EmployeesList;
posted @ 2022-05-29 19:41  遥月  阅读(541)  评论(0)    收藏  举报