相关文章推荐
大鼻子的煎鸡蛋  ·  如何:使用 LINQ ...·  1 周前    · 
慷慨大方的皮带  ·  在Razor Page ...·  1 周前    · 
犯傻的绿茶  ·  C# 之 ...·  20 小时前    · 
奔跑的西瓜  ·  SQL ...·  1 周前    · 
完美的鸵鸟  ·  PowerShell:输出cmdlet - ...·  1 月前    · 
闷骚的红薯  ·  excel ...·  6 月前    · 
老实的绿茶  ·  JavaScript 的 ...·  1 年前    · 

才工作时对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; get; }
        public string Name { set; get; }
        public int DepId { set; get; }
        public DateTime AttendTime { set; get; }
    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无论大小都能将数据处理变得更轻松,便捷。
    在此也鞭策自己,不为前端接口考虑后端性能优化的程序员,不是一个合格的全栈(/笑

    分类:
    后端
    标签: