一、linq的基本概念

  LINQ是C#和VB中的统一查询语法,使用对象来保存和检索来自不同来源(如数据库、xml、对象集合)的数据。

  主要功能:消除了编程语言和数据库之间的不匹配,以及为不同类型的数据源提供统一的查询接口。

  适用范围:LInq适用于实现了IEnumerable <T>(IQueryable继承于IEnumerable )的实例,如:List,Dictionary,Queue,LinkedList,Array等

二、linq的使用

  有两种方法可以将LINQ查询写入IEnumerable集合或IQueryable数据源。

  1、查询语法

    特点:以from子句开头,可以以select或groupBy子句结束

  2、lambda表达式(简洁且功能更多,推荐)

  下边给出了简单的例子,注:后边的部分都是使用的这个测试数据。

   //准备的测试数据
IList<UserInfo> userList = new List<UserInfo>() {
new UserInfo() { UId = , UserName = "zs", Age = ,RoleId=} ,
new UserInfo() { UId = , UserName = "ls", Age = ,RoleId=},
new UserInfo() { UId = , UserName = "ww", Age = ,RoleId=},
new UserInfo() { UId = , UserName = "zl", Age = ,RoleId=},
new UserInfo() { UId = , UserName = "tq", Age = ,RoleId=}
};//用户列表
IList<RoleInfo> roleList = new List<RoleInfo>(){
new RoleInfo(){Rid=,RoleName="管理员"},
new RoleInfo(){Rid=,RoleName="普通用户"},
};//角色列表 //query语法
var resUsers = from u in userList
where u.Age >
select new {u.UId,u.UserName,u.Age};
//lambda
var resUsers2 = userList.Where<UserInfo>(u => u.Age > ).Select
                  (u => new { u.UId,u.UserName,u.Age});

三、linq详解

1、过滤 (where 和 oftype)

  Where:根据给定的条件表达式过滤集合,并返回一个新集合

  OfType:根据类型进行过滤

        IList<object> list = new List<object>() { , "hello", user };//user是一个UserInfo的实例
//query语法
  var result = from o in list.OfType<string>()
  select o;
//lambda语法
   var result2 = list.OfType<string>();

2、排序(OrderBy,OrderByDescending,ThenBy,ThenByDescending)

     //对userList先按Id排序,再按Age排序
//query语法
var result = from u in userList
orderby u.Id,u.Age descending
select u;
//lambda语法
var result2 = userList.OrderByDescending(u => u.Id).ThenBy(u=>u.Age);

3、分组(group by,ToLookUp)

       //query语法
var resGroups = from u in userList
group u by u.RoleId;
//lambda方式 注:GroupBy延迟执行,而ToLookup是立即执行的,使用方法和GroupBy一样。
var resGroups2 = userList.GroupBy(u => u.RoleId);
//遍历(group.Key为设置分组的列的值)
foreach (var group in resGroups)
{
Console.WriteLine("roleId:{0}", group.Key);
foreach (UserInfo user in group)
{
Console.WriteLine("UserName:{0}", user.UserName);
}
}
/*结果: roleId:1
UserName:zs
UserName:ww
roleId:2
UserName:ls
UserName:zl 21 UserName:tq */ //多列分组
var productGroup=
from p in db.Products
group p by new
{
p.PName,
p.PColor
}
into g
select new
{
g.Key,//这里的key是一个对象,有两个属性:PName,PColor
g
};

4、连接查询(join)

   //query语法,查询用户名和该用户所属的角色 inner join
var resJoin = from user in userList
join role in roleList
on user.RoleId equals role.Rid
select new
{
uname=user.UserName,
rname=role.RoleName
};
 
//left join,right join调整下顺序即可
var resJoin = from user in userList
join role in roleList
on user.RoleId equals role.Rid into temp
   from tt in temp.DefaultIfEmpty
select new
{
uname=user.UserName,
rname=role?.RoleName
};
//cross join
var resJoin = from user in userList
from role in roleList
select new
{
uname=user?.UserName,
rname=role?.RoleName
}; //lambda方式
var resJoin2 = userList.Join(roleList,
user => user.RoleId, //outkey
role => role.Rid, //innerkey
(user, role) => new //result
{
uname = user.UserName,
rname = role.RoleName
});
//遍历
foreach (var item in resJoin2)
{
Console.WriteLine("用户:{0}----角色:{1}", item.uname, item.rname);
} /*结果: 用户:zs----角色:管理员
用户:ls----角色:普通用户
用户:ww----角色:管理员
用户:zl----角色:普通用户
用户:tq----角色:普通用户 */

5、linq中的量词(All,Any,Contains)

     //All 所有元素都符合条件返回true
bool areAllAdmin = userList.All(u => u.RoleId == ); //所有用户的roleid都是1--->false
//Any 有一个符合条件就返回true
bool isAnyAdmin = userList.Any(u => u.RoleId == );//用户里有没有roleid为1的 --> true
//Contains 包含返回true
UserInfo user1=new UserInfo() { UId = , UserName = "zs", Age = , RoleId = };
//contains比较的是索引,所以就是list中有一个属性都相同的元素也会返回false,我们可以自定义一个比较类CompareUser来解决这个问题
bool isContains = userList.Contains(user1);//s索引不同:false
bool isContains2=userList.Contains(user1,new CompareUser());//自定义比较:true //自定义的userinfo比较器
public class CompareUser : IEqualityComparer<UserInfo>
{
public bool Equals(UserInfo x, UserInfo y)
{
bool isSame = false;
//age,username,roleid相同,我们就认为是同一个userinfo
if (x.Age==y.Age&&x.UserName==y.UserName&&x.RoleId==y.RoleId)
{
isSame=true;
}
return isSame;
}
public int GetHashCode(UserInfo obj)
{
throw new NotImplementedException();
}
}

6、聚合函数(Average,Count,Max,Min,Sum)

   //平均年龄:28.8
var avgAge = userList.Average(u => u.Age);
//用户人数:5: 大于30岁的用户人数:2
var userCount = userList.Count();
var olduserCount = userList.Count(u => u.Age > );
//最大年龄:42
var maxAge = userList.Max(u => u.Age);
//最小年龄:20
var minAge = userList.Min(u => u.Age);
//年龄和:144
var sumAge = userList.Sum(u => u.Age);

7、元素操作符(ElementAt,Frist,Last,Singe和对应的xxxOrDefault)

    这些操作符加上OrDefault后缀后,在超出索引时不会抛出异常,而是返回一个默认值,(如:int返回0 ,引用类型返回null)

 1     //获取指定索引处的元素
UserInfo user0 = userList.ElementAt();
UserInfo user9 = userList.ElementAtOrDefault();
//不报错,返回null,没有ordefault后缀会抛异常
//获取第一个元素
UserInfo userfrist = userList.First();
UserInfo userfrist2 = userList.FirstOrDefault();
//获取最后一个元素
UserInfo userlast = userList.Last();
UserInfo userlast2 = userList.LastOrDefault();
//获取唯一元素()
UserInfo userSignal = userList.Single(u => u.Age < );
UserInfo userSignal2 = userList.SingleOrDefault(u => u.Age > );
         //报错,返回的元素不是唯一的

8、判断序列相等(SequenceEqual)

  //原始类型(字符串、int等,比较顺序和值,这两项都相等时返回true)
IList<int> intList1 = new List<int> { , , , };
IList<int> intList2 = new List<int> { , , , };
//bool isEquel = intList1.SequenceEqual(intList2); //复杂类型(UserInfo,比较索引,索引相同返回true,可通过自定义比较器修改比较的规则)
UserInfo user1 = new UserInfo() { UId = , UserName = "zs", Age = , RoleId = };
UserInfo user2 = new UserInfo() { UId = , UserName = "zs", Age = , RoleId = };
IList<UserInfo> list1 = new List<UserInfo>() { user1 };
IList<UserInfo> list2 = new List<UserInfo>() { user2};
//user1和user2的索引不同,返回false
bool isEquel = list1.SequenceEqual(list2);
//自定义比较器,只要属性都相等返回true
bool isEquel2 = list1.SequenceEqual(list2, new CompareUser()); //自定义的userinfo比较器
public class CompareUser : IEqualityComparer<UserInfo>
{
public bool Equals(UserInfo x, UserInfo y)
{
bool isSame = false;
//age,username,roleid相同,我们就认为是同一个userinfo
if (x.Age==y.Age&&x.UserName==y.UserName&&x.RoleId==y.RoleId)
{
isSame=true;
}
return isSame;
}
public int GetHashCode(UserInfo obj)
{
throw new NotImplementedException();
}
}

9、集合操作(Concat、Distinct、Except、Intersect、Union)

      //合并 Concat
IList<UserInfo> list1 = new List<UserInfo>() { user1,user2,user1 };
IList<UserInfo> list2 = new List<UserInfo>() { user2 ,user2};
var listConcat = list1.Concat(list2);
        //包含了user1,user2,user1,user2,user2
//去重 Distinct(差并交集会自动去重,去重和交差并集中的复杂类型也是根据索引来判断是否相同的,所以视情况自定义比较器)
var list4 = list1.Distinct();//user1,user2
//差集(list1中有,list中没有的)
var list5 = list1.Except(list2);//user1
//交集
var list6 = list1.Intersect(list2);//user2
//并集
var list7 = list1.Union(list2);//user1,user2

10、分区(Skip,SkipWhile,Take,TakeWhile)

      //分区
var resUsers = userList.Skip();//跳过前2条,返回从第3条到最后一条的记录
var resUsers2 = userList.SkipWhile(u => u.Age < ); // 跳过满足条件的数据
//结果:从年龄为33的开始,返回后几条 var resTake = userList.Take();//取前2条数据
var resTake2 = userList.TakeWhile(u => u.Age >= );
//取满足条件的数据,如果连续几条都满足返回多条记录,直到某一条数据不满足条件
//结果:返回第一条,如果把条件中22改成20,那么返回所有数据

11、类型转化(As,To,Cast)  select 默认返回的是IEnumerable类型

        var users = from u in userList select u; //IEnumerable<UserInfo>
var usersEnum = (from u in userList select u).AsEnumerable<UserInfo>();//IEnumerable<UserInfo>
var usersCast = (from u in userList select u).Cast<UserInfo>();//IEnumerable<UserInfo>,功能和AsEnumerable一样,写着简单
var usersQuery = (from u in userList select u).AsQueryable<UserInfo>();//IQueryable<UserInfo>
var usersArray = (from u in userList select u).ToArray<UserInfo>();//UserInfo[]
var usersList = (from u in userList select u).ToList<UserInfo>();//List<UserInfo>
var usersDic = (from u in userList select u).ToDictionary<UserInfo,int>(u=>u.UId);//Dictionary<int,UserInfo>

linq总结系列(一)---基础部分的更多相关文章

  1. LINQ学习系列-----1.3 扩展方法

    这篇内容继续接着昨天的Lambda表达式的源码继续下去.昨天讲了Lambda表达式,此篇讲扩展方法,这两点都是Linq带来的新特性.    一.扩展方法介绍   废话不多说,先上源码截图: 上图中Ge ...

  2. 「译」JUnit 5 系列:基础入门

    原文地址:http://blog.codefx.org/libraries/junit-5-basics/ 原文日期:25, Feb, 2016 译文首发:Linesh 的博客:JUnit 5 系列: ...

  3. [WPF系列]从基础起步学习系列计划

    引言 WPF技术已经算不什么新技术,一搜一大把关于WPF基础甚至高级的内容.之前工作中一直使用winform所以一直没有深入学习WPF,这次因项目中使用了WPF技术来实现比较酷的展示界面.我在这里只是 ...

  4. 快速入门系列--WebAPI--01基础

    ASP.NET MVC和WebAPI已经是.NET Web部分的主流,刚开始时两个公用同一个管道,之后为了更加的轻量化(WebAPI是对WCF Restful的轻量化),WebAPI使用了新的管道,因 ...

  5. Java 之 I/O 系列 01 ——基础

    Java 之 I/O 系列 目录 Java 之 I/O 系列 01 ——基础 Java 之 I/O 系列 02 ——序列化(一) Java 之 I/O 系列 02 ——序列化(二) 整理<疯狂j ...

  6. Linq学习系列

    LINQ之路系列博客导航 http://www.cnblogs.com/lifepoem/archive/2011/12/16/2288017.html LINQ体验系列文章导航 http://www ...

  7. (C#)Windows Shell 编程系列1 - 基础,浏览一个文件夹

    原文 (C#)Windows Shell 编程系列1 - 基础,浏览一个文件夹 (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢-) Windows Shell 编程,即 Windows ...

  8. Windows 8实例教程系列 - 数据绑定基础实例

    原文:Windows 8实例教程系列 - 数据绑定基础实例 数据绑定是WPF,Silverlight以及Windows Phone应用开发中最为常用的开发技术,在基于XAML的Windows Stor ...

  9. LINQ学习系列-----2.3 迭代器带来的延迟查询

    此篇博文承接上一篇博文: LINQ学习系列-----2.2 迭代器 一.第一次执行                      废话不多说,上源码: 执行结果下图: 为什么会这样?其实原因很简单 fro ...

  10. [转]快速入门系列--WebAPI--01基础

    本文转自:http://www.cnblogs.com/wanliwang01/p/aspnet_webapi_base01.html ASP.NET MVC和WebAPI已经是.NET Web部分的 ...

随机推荐

  1. LOJ2250 [ZJOI2017] 仙人掌【树形DP】【DFS树】

    题目分析: 不难注意到仙人掌边可以删掉.在森林中考虑树形DP. 题目中说边不能重复,但我们可以在结束后没覆盖的边覆盖一个重复边,不改变方案数. 接着将所有的边接到当前点,然后每两个方案可以任意拼接.然 ...

  2. [USACO2008 Mar]土地购买

    传送门:>HERE< 题意:购买一组土地的费用是最长的长乘以最长的宽.现给出n块土地,求购买所有土地(可以将土地分为任意组,不需按顺序)的最小费用 解题思路 动态规划+斜率优化 斜率优化在 ...

  3. Python FAQ

    1.在函数a中又定义了函数sum,内部函数sum可以引用外部函数a的参数n,不能这样写n=n+1,两个会出错,这样写s=s+n可以 解决: def a(): n = 1 def sum(): nonl ...

  4. bzoj 2653: middle (主席树+二分)

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2522  Solved: 1434[Submit][Status][Disc ...

  5. 每天一个linux命令(1):wc命令

    Linux系统中的wc(Word Count)命令的功能为统计指定文件中的字节数.字数.行数,并将统计结果显示输出. 1.命令格式: wc [选项]文件... 2.命令功能: 统计指定文件中的字节数. ...

  6. 小程序-camera

    camera 使用这个组件使用手机的拍摄功能.实现如下操作 打开拍摄画面,在手机上半屏显示拍摄取景,下面有一个拍摄按钮.点击后,取景器位置显示拍摄画面,下面显示确定取消按钮. 确定后,下方的预览图片列 ...

  7. bzoj1226/luogu2157 学校食堂 (状压dp)

    我们先约定:(左) 窗口_人人人人人 (右) 可以发现,我们只需要知道最靠左的还没打饭的人 以及它身后7个人的状态 以及上一个打饭的人是谁 因为他左面的就都打过了 右面7个人以后肯定还没打 可以设f[ ...

  8. BZOJ--1045-- 糖果传递(中位数,排序)

    题目链接 :BZOJ--1045-- 糖果传递 我们知道如果不头尾相连的话 直接求一个前缀和 答案为ans+=s[i] 不相连的话就是1 和n之间断开 头尾相连的话就是 在第k个人之间断开 设A[i] ...

  9. 【CF131D】Subway

    题目大意:给定一棵 N 个节点的基环树,求各个点到环的最小距离. 题解:除了找环的必须参数之外,对每个点维护一个 fa 即可. 代码如下 #include <bits/stdc++.h> ...

  10. 透彻掌握Promise的使用

    Promise的重要性我认为我没有必要多讲,概括起来说就是必须得掌握,而且还要掌握透彻.这篇文章的开头,主要跟大家分析一下,为什么会有Promise出现. 在实际的使用当中,有非常多的应用场景我们不能 ...