才工作时对Linq了解很少,结果工作上的难题证明了做后端编码,就一定要学会Linq。
首先不得不吹一波Microsoft的大神们,把Linq这个基础包做的非常厉害,
.Net Framework 3.5 以上直接引入命名空间就可以使用了。
using System.Linq;
复制代码
这篇文章到底要表达什么
这不是写技术教程,也不是搬运官方文档,很多技术也是受别人指教学习。
分享我在项目中实际遇到的问题,不同于网上的Demo教程。
欢迎指出我的不足,谢谢。
案例一:多个list关联查询。
初始化代码
public class Person()
public int Cardnum {get;set;}
public string Name {get;set;}
public Empinfo Info {get;set;}
public class Empinfo()
public int DepId { get; set;}
public string WorkNum {get;set;}
public class Department()
public int Id {get;set;}
public string Name {get;set;}
List<Department> dep = new List<Department>()
new Department(){ Id = 1, Name = "开发部"},
new Department(){ Id = 2, Name = "背锅部"},
new Department(){ Id = 3, Name = "运营部"}
List<Person> per = new List<Person>()
new Person(){ Cardnum= 1, Name = "张三", Info = new Empinfo() { DepId = 1,WorkNum = "第一组" } },
new Person(){ Cardnum= 2, Name = "李四", Info = new Empinfo() { DepId = 2,WorkNum = "第二组" } },
new Person(){ Cardnum= 3, Name = "王五", Info = new Empinfo() { DepId = 3,WorkNum = "第三组" } },
new Person(){ Cardnum= 4, Name = "赵六", Info = new Empinfo() { DepId = 1,WorkNum = "第一组" } },
new Person(){ Cardnum= 5, Name = "陈七", Info = new Empinfo() { DepId = 2,WorkNum = "第二组" } }
可以看到以上的人员和部门关联点是在于 per.info.depId == dep.Id
需求是根据per查询出每个部门下有多少人。
先来一段传统代码
public class Templist()
public int DepId { get; set;}
public string Name {get;set;}
public int Count {get;set}
List<Templist> temps = new List<Templist>();
foreach(depitem in dep )
foreach(pitem in per)
if(pitem.info.DepId == depitem.Id)
temps.add()
当然还有性能更差一点的for循环也可以实现。
我的上述代码还没写完:判断temps是否重复,count++统计,是否有null的情况……
完成这个功能估计要是30行左右的代码。 是不是非常繁琐?
linq 优化
Join操作符。常应用于将多个数据源相联接,根据数据源中相等的值进行匹配
var result = from d in dep
join p in per on dep.Id equals p.EmpInfo.DepId
into g
select new
DepartId = d.Id,
DepartName = d.Name,
Count = g.Count()
看到这里我相信没有使用过Linq的同学一定开始惊讶Linq的魔力了。
减少代码并不是关键,而把复杂的嵌套循环直接改用类似T-SQL的语法,既减轻了代码复杂度,又提升了美观。
案例二: 去重和查询
存在多条重复数据时,该怎么查询和去重呢?
去重的条件一般都是指向性:比如要求通过卡号去重,保留考勤时间最大的一条。
public class AttendInfo
public int CardNum { set
public string Name { set
public int DepId { set
public DateTime AttendTime { set
List<AttendInfo> lists = new List<AttendInfo>()
new AttendInfo(){ CardNum = 1, Name = "张三", DepId = 1, AttendTime = DateTime.Parse("2019-01-01 00:00:00")},
new AttendInfo(){ CardNum = 1, Name = "张三", DepId = 1, AttendTime = DateTime.Parse("2019-01-02 00:00:00")},
new AttendInfo(){ CardNum = 2, Name = "李四", DepId = 2, AttendTime = DateTime.Parse("2019-01-03 00:00:00")},
new AttendInfo(){ CardNum = 2, Name = "李四", DepId = 2, AttendTime = DateTime.Parse("2019-01-04 00:00:00")},
new AttendInfo(){ CardNum = 3, Name = "王五", DepId = 3, AttendTime = DateTime.Parse("2019-01-05 00:00:00")},
new AttendInfo(){ CardNum = 3, Name = "王五", DepId = 3, AttendTime = DateTime.Parse("2019-01-06 00:00:00")},
new AttendInfo(){ CardNum = 4, Name = "赵六", DepId = 4, AttendTime = DateTime.Parse("2019-01-07 00:00:00")}
Linq官方给出的建议是: lists.Distinct()
但是这个方法在实际项目中很少能用到,因为你的数据结构不可能这么单一
并且还带有搜索条件,所以应该这么写.
var temp = from ls in lists
group ls by ls.CardNum
into g
select new
CardNum = g.Key,
Name = g.Max(e => e.Name),
DepId = g.Max(e => e.DepId),
AttendTime = g.Max(e => e.AttendTime)
group by 分组后,操作对象非常轻松。
复制代码
结束语
这些小案例只是Linq的常规用法,但能发现Linq无论大小都能将数据处理变得更轻松,便捷。
在此也鞭策自己,不为前端接口考虑后端性能优化的程序员,不是一个合格的全栈(/笑