一、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. centos部署nextcloud

    简介 Nextcloud是一套用于创建和使用文件托管服务的客户端-服务器软件.它在功能上类似于Dropbox,虽然Nextcloud是免费的和开源的,允许任何人在私人服务器上安装和操作它.与Dropb ...

  2. 机器学习---朴素贝叶斯分类器(Machine Learning Naive Bayes Classifier)

    朴素贝叶斯分类器是一组简单快速的分类算法.网上已经有很多文章介绍,比如这篇写得比较好:https://blog.csdn.net/sinat_36246371/article/details/6014 ...

  3. 【BZOJ5304】[HAOI2018]字串覆盖(后缀数组,主席树,倍增)

    [BZOJ5304][HAOI2018]字串覆盖(后缀数组,主席树,倍增) 题面 BZOJ 洛谷 题解 贪心的想法是从左往右,能选就选.这个显然是正确的. 题目的数据范围很好的说明了要对于询问分开进行 ...

  4. linux ./configure check your system clock

    checking for a BSD-compatible install... /usr/bin/install -cchecking whether build environment is sa ...

  5. [luogu3810][bzoj3262][陌上花开]

    题目链接 思路 听说可以CDQ分治,然后我不会,所以我写树套树 首先肯定先按照a拍个序.然后就成了在b,c这两个数组中查询了.用一个树状数组套treap来维护.当插入一个数的时候,就在树状数组的b这个 ...

  6. 每添加一张图片后,GDI对象 + 3 原因: ImageList_AddIcon(hIcon) 后没调用 DestroyIcon(hIcon)

    今天无意间在[任务管理器]中发现,每添加1张图片后,应用程序的 GDI对象 + 3,添加图片后,再把所有图片删除, GDI对象数量没减少! 排查原因,发现: GDI对象 + 3 的代码是: int o ...

  7. C#面向对象中类的继承和扫描顺序和接口

    1.   类的分类:普通基类.抽象基类(abstract  class)1.   类的扫描顺序:a.先近后远 b.(向上扫描)以谁身份声明的变量就在谁身上开始扫描, 2.   扫描的特殊情况:普通基类 ...

  8. python--数据类型bytes

    在Python3以后,字符串和bytes类型彻底分开了.字符串是以字符为单位进行处理的,bytes类型是以字节为单位处理的. bytes数据类型在所有的操作和使用甚至内置方法上和字符串数据类型基本一样 ...

  9. c/c++ 大于等于 大于 时间效率比较

    变成汇编,都是: 大于等于和大于都是电路上的处理,时间上应该差不多.

  10. Redis命令:scan实现模糊查询

    转: Redis命令:scan实现模糊查询 2017年12月31日 16:54:33 琦彦 阅读数:22893 标签: redis数据库Redis命令scan模糊查询 更多 个人分类: Redis 所 ...