LINQ详细的介绍

基础数据搞一下

//先定义一个类
 public   class StudentModel 
    {
      public   int index { get; set; }

        public string Name { get; set; }

        public string Sex { get; set; }
      
    }
//存一点测试数据

List<StudentModel> modes = new List<StudentModel>();
            modes.Add(new StudentModel() { index=1, Name="a", Sex=""});
            modes.Add(new StudentModel() { index = 2, Name = "b", Sex = "" });
            modes.Add(new StudentModel() { index = 3, Name = "c", Sex = "" });
            modes.Add(new StudentModel() { index = 4, Name = "d", Sex = "" });
            modes.Add(new StudentModel() { index = 5, Name = "e", Sex = "" });
            modes.Add(new StudentModel() { index = 5, Name = "f", Sex = "0.5" });
            modes.Add(new StudentModel() { index = 5, Name = "g", Sex = "0.5" });  

Linq--where 

//单条件查询
var smlist = modes.Where(a => a.Sex == "").ToList(); foreach(StudentModel sm in smlist) { Console.WriteLine(sm.Name+":"+sm.Sex); }
//多条件查询或者
            var smlist1 = modes.Where(a => a.Sex == "" || a.Sex.Contains("0.5")).ToList();
            foreach (StudentModel sm in smlist1)
            {
                Console.WriteLine(sm.Name + ":" + sm.Sex);
            }
 //多条件查询并且
            var smlist2 = modes.Where(a => a.Name == "f" && a.Sex.Contains("0.5")).ToList();
            foreach (StudentModel sm in smlist2)
            {
                Console.WriteLine(sm.Name + ":" + sm.Sex);
            }
//返回列表正序排列OrderBy,倒序排列OrderByDescending
            var smlist3 = modes.Where(a => a.Sex == "").OrderBy(a=>a.Name).ToList();
            foreach (StudentModel sm in smlist3)
            {
                Console.WriteLine(sm.Name + ":" + sm.Sex);
            }
//distinct去重
            var smlist3 = modes.Where(a => a.Sex == "").OrderBy(a=>a.Name).ToList().Distinct();
            foreach (StudentModel sm in smlist3)
            {
                Console.WriteLine(sm.Name + ":" + sm.Sex);
            }

在这我说几句:以上意思就是 取出sex字段为 ‘男’并且排序,形成列表后在进行排序。

像distinct 这种操作可以自由的跟你你的需求去使用,到底是先排序再去重啊,还是先去重再排序啊,完全根据你的需求。

//返回满足条件的第一个结果first,最后一个last ,如果没有满足条件的时候会报错,经过多方询问,这俩的是在确定有数据的时候才会使用,执行相率相比FirstOrDefault快
            var  smlist3 = modes.Where(a => a.Sex == "").First();
                Console.WriteLine(smlist3.Name + ":" + smlist3.Sex);
//返回满足条件的第一个结果FirstOrDefault,最后一个lastDefault,没有符合条件的结果的时候不会报错
            var  smlist3 = modes.Where(a => a.Sex == "").FirstOrDefault();
                Console.WriteLine(smlist3.Name + ":" + smlist3.Sex);

Linq-select 

//这个地方是两种不同的书写方法大体看看就行          
var query = from StudentModel in modes select new {StudentModel.Name,StudentModel.Sex,StudentModel.index }; foreach (var sm in query) { Console.WriteLine(sm.Name + ":" + sm.Name); } var ssrr = modes.Select(a => new { a.Name, a.index, a.Sex }).ToList(); foreach (var sm in query) { Console.WriteLine(sm.Name + ":" + sm.Name); }
//select 我理解的就是设置查询的列,或者对象,并且赋值
            var ssrr = modes.Select(a => new StudentModel { Name=a.Name,Sex=a.Sex,index= a.index }).ToList();
            foreach (StudentModel sm in ssrr)
            {
                Console.WriteLine(sm.Name + ":" + sm.Sex);
            }

在这多说一句,这个的意思就是从models 里面取出数来,放到StudentModel里面,并设置相应的对应列的值。看看下面加强理解一下

    class shortModel
    { 
        public string name { get; set; }
        public string sex { get; set; }
    }
            var ssrr = modes.Select(a => new shortModel { name=a.Name,sex=a.Sex}).ToList();
            foreach (shortModel sm in ssrr)
            {
                Console.WriteLine(sm.name + ":" + sm.name);
            }
//select  调用自定义的方法
        static string ReturnSex(string sex)
        {
            if (sex == "0.5")
            {
                return "待检测";
            }
            else
            {
                return "合格";
            }
        }
var ssrr = modes.Select(a => new shortModel { name=a.Name,sex= ReturnSex(a.Sex) }).ToList();
            foreach (shortModel sm in ssrr)
            {
                Console.WriteLine(sm.name + ":" + sm.name);
            }

Linq-Skip Take

//跳过几行数据(默认从第一行开始),结合排序最佳
            var ssrr = modes.Select(a => new { a.Name, a.index, a.Sex }).Skip(2).ToList();
            foreach (var sm in ssrr)
            {
                Console.WriteLine(sm.Name + ":" + sm.Name);
            }
        }
//截取几行数据(默认从第一行开始),结合排序最佳
 var ssrr = modes.Select(a => new { a.Name, a.index, a.Sex }).Take(2).ToList(); 
foreach (var sm in ssrr)
{
Console.WriteLine(sm.Name
+ ":" + sm.Name);
}

Linq-Skipwhile TakeSkipwhile 

//条件跳过,或者截取
var
ssrr = modes.SkipWhile(a=>a.Name.Contains("a")).ToList(); foreach (var sm in ssrr) { Console.WriteLine(sm.Name + ":" + sm.Name); }

Linq-Join

 List<Class> modeClass = new List<Class>();
            modeClass.Add(new Class() {  id=1, ClassName="一班"});
            modeClass.Add(new Class() { id =2, ClassName = "二班" });
            List<StudentModel> modeStudent = new List<StudentModel>();
            modeStudent.Add(new StudentModel() { index=1, Name="a", Sex=""});
            modeStudent.Add(new StudentModel() { index = 2, Name = "b", Sex = "", ClassID=1 });
            modeStudent.Add(new StudentModel() { index = 3, Name = "c", Sex = "", ClassID = 1 });
            modeStudent.Add(new StudentModel() { index = 4, Name = "d", Sex = "",ClassID = 1 });
            modeStudent.Add(new StudentModel() { index = 5, Name = "e", Sex = "" , ClassID = 1 });
            modeStudent.Add(new StudentModel() { index = 5, Name = "f", Sex = "0.5" ,ClassID = 2 });
            modeStudent.Add(new StudentModel() { index = 5, Name = "g", Sex = "0.5", ClassID = 2 });

            var res = from a in modeStudent join b in modeClass on a.ClassID equals b.id select new { a.Name,b.ClassName };
            foreach (var sm in res)
            {
                Console.WriteLine(sm.Name + ":" + sm.ClassName);
            }

Linq ----GroupJoin

//GroupJoin其实就是join 配合 into 使用,类似于group by 
            var query = from c in modeClass
                        join o in modeStudent on c.id equals o.ClassID into os
                        select new { c, os };
            foreach (var item in query)
            {
                Console.WriteLine(item.c.ClassName);
                foreach (var o in item.os)
                {
                    Console.WriteLine(o.Name+o.Sex);
                }
            }

//以班级为主信息对学生进行归类
            var query = modeClass.GroupJoin(modeStudent, a => a.id, b => b.ClassID, (a, t) => new { ID = a.id, ClassName = a.ClassName, UserIDs = string.Join(",", t.Select(x => x.Name.ToString()).ToArray()) });
            foreach(var sttt in query)
            {
                Console.WriteLine(+sttt.ID+":"+sttt.ClassName+":"+sttt.UserIDs+":");
            }

 

 

 简单解释一下(自己的理解),首先确定归类的主表,也就是modelclass班级表,MOdelStudelt是学生表看做子表。根据主表形成子表的集合。

linq----concat 不去重直接合并,速度较快,Union 去重后合并,用法二者完全一致。

            List<StudentModel> modeStudent01 = new List<StudentModel>();
            modeStudent01.Add(new StudentModel() { index=1, Name="a", Sex="", ClassID = 1 });
            modeStudent01.Add(new StudentModel() { index = 2, Name = "b", Sex = "", ClassID=1 });
            modeStudent01.Add(new StudentModel() { index = 3, Name = "c", Sex = "", ClassID = 1 });
            modeStudent01.Add(new StudentModel() { index = 4, Name = "d", Sex = "",ClassID = 1 });
            modeStudent01.Add(new StudentModel() { index = 5, Name = "e", Sex = "" , ClassID = 1 });
            modeStudent01.Add(new StudentModel() { index = 6, Name = "f", Sex = "0.5" ,ClassID = 2 });
            modeStudent01.Add(new StudentModel() { index = 7, Name = "g", Sex = "0.5", ClassID = 2 });


            List<StudentModel> modeStudent02 = new List<StudentModel>();
            modeStudent02.Add(new StudentModel() { index = 8, Name = "a", Sex = "", ClassID = 1 });
            modeStudent02.Add(new StudentModel() { index = 9, Name = "b", Sex = "", ClassID = 1 });
            modeStudent02.Add(new StudentModel() { index = 10, Name = "c", Sex = "", ClassID = 1 });
            modeStudent02.Add(new StudentModel() { index = 11, Name = "d", Sex = "", ClassID = 1 });

 

 //单列合并成一个表·
            var exet = (from a in modeStudent01 select a.Name).Concat(from b in modeStudent02 select b.Name);
            foreach (var item in exet)
            {
                Console.WriteLine(item);
            }
 //多列合并成一个表·
            var exet = modeStudent01.Select(a => new { a.Name, a.Sex, a.index }).Concat(modeStudent02.Select(b=>new { b.Name,b.Sex,b.index}));
            foreach (var item in exet)
            {
                Console.WriteLine(item.Name+ item.Sex+item.index);
            }

linq----OrderBy,OrderByDescending 这俩不需要解释了吧,形成列表后进行排序或者排序后形成列表,随意

linq----ThenBy,ThenByDescending

 //ThenBy,ThenByDescending 是对列表进行orderby之后在进行的排序
            var result = modeStudent01.OrderBy(a => a.index).ThenBy(a=>a.Name);
            foreach(StudentModel sm in result)
            {
                Console.WriteLine("index:"+sm.index +"姓名:"+ sm.Name );
            }

linq---- Reverse 对查询结果反向排序

  //这是一组对比
            var result = modeStudent01.OrderBy(a => a.index).ThenBy(a=>a.Name);
            foreach(StudentModel sm in result)
            {
                Console.WriteLine("index:"+sm.index +"姓名:"+ sm.Name );
            }
var result = modeStudent01.OrderBy(a => a.index).ThenBy(a=>a.Name).Reverse();
            foreach(StudentModel sm in result)
            {
                Console.WriteLine("index:"+sm.index +"姓名:"+ sm.Name );
            }

结果这两种方式自己对比一下

 linq----group by 合并去重

//实例
var
result = from o in modeStudent01 group o by o.index; foreach(var stu in result) { Console.WriteLine("分组名称:"+stu.Key); foreach (var tt in stu) { Console.WriteLine("姓名:"+tt.Name+"; 性别:"+tt.Sex); } }
//多列合并去重           
var result = from o in modeStudent01 group o by new { o.Name, o.Sex, o.index }; foreach(var stu in result) { Console.WriteLine("姓名:"+stu.Key.Name+" 性别:"+stu.Key.Sex); }

 linq----Distinct

//指定需要去重的列,然后去重
            var result = modeStudent01.Select(a => new { a.index, a.Name, a.Sex, a.ClassID }).Distinct().ToList();
            foreach (var rr in result)
            {
                Console.WriteLine(rr.Name);
            }

linq----InterSect 集合相交

//指定的列,验证相交的部分
            var result = modeStudent01.Select(a=>new { a.Name,a.index,a.Sex}).Intersect(modeStudent02.Select(a=> new { a.Name,a.index,a.Sex})).ToList();
            foreach (var rr in result)
            {
                Console.WriteLine(rr.Name);
            }

linq----Except 集合差

//指定的列,验证集合相差的部分
            var result = modeStudent01.Select(a=>new { a.Name,a.index,a.Sex}).Except(modeStudent02.Select(a=> new { a.Name,a.index,a.Sex})).ToList();
            foreach (var rr in result)
            {
                Console.WriteLine(rr.Name);
            }

linq----AsEnumerable and AsQueryable 

//AsEnumerable,AsQueryable
            var res = (from a in modeStudent01.AsEnumerable() select a);
            var res12 = (from a in modeStudent01.AsQueryable() select a);

linq----ToArray

//类型转换成,数字
            int[] arr = { 1, 2, 3, 4 };
            var query = from element in arr
                        orderby element
                        select element;
            int[] array2 = query.ToArray();

linq----Dictionary

//转换成dic,并取值
            Dictionary<int, string> dic = modeStudent01.ToDictionary(c => c.index, c => c.Sex);
            foreach(int ss in dic.Keys)
            {
                Console.WriteLine(ss+":"+dic[ss]);
            }

linq----ToLookkup

//一个key要求对应多个value情况ToLookup方法是非常有用的
            var dic = modeStudent01.ToLookup(c => c.index);
            foreach(var ss in dic)
            {
                Console.WriteLine("学生ID号:" + ss.Key);

                foreach (var item1 in ss)
                {
                    Console.WriteLine("\t\t" + item1 + " || " + item1.Name + " || " + item1.Sex);
                }
            }

linq---ofType

 //从一个集合中取出你想得到的数据类型的值
            var num = new object[] { 1, 2, "a", "b", 4 };
            foreach(var an in num.OfType<int>())
            {
                Console.WriteLine(an);
            }

linq----Cast

//用来将非泛型的序列转换为泛型的序列
            List<string> listStr = new List<string>();
            listStr.Add("张三");
            listStr.Add("李四");
            listStr.Add("王五");
            
            var  qqq = listStr.Cast<string>();
           foreach(string sst in qqq)
            {
                Console.WriteLine(sst);
            }

linq----first  last  不存在报错。FirstOrDefault LastOrDefault 不存在返回默认值   执行效率上 first last 快点。

linq----SelectMany 迪卡尔积运算

var list1 = new List<string> { "a1", "a2" };
var list2 = new List<string> { "b1", "b2", "b3" };

合并这俩集合

var result = list1.SelectMany(x => list2.Select(y => $"{x}{y}"));

linq----Aggregate    将内容合在一起

string[] stringList = { "Hello", "World", "!" };
string joinedString = stringList.Aggregate((prev, current) => prev + " " + current);

result: joinedString = "Hello World !"

linq----SkipWhile(从起始位置开始忽略元素,直到匹配到符合条件的元素停止忽略,往后就是要查询的结果;) TakeWhile (从起始位置开始读取符合条件的元素,一旦遇到不符合条件的就停止读取,即使后面还有符合条件的也不再读取。)

int[] list = { 42, 42, 6, 6, 6, 42 };
var result = list.SkipWhile(i => i == 42);
// result: 6, 6, 6, 42


int[] list = { 1, 10, 40, 50, 44, 70, 4 };
var result = list.TakeWhile(item => item < 50).ToList();
// result = { 1, 10, 40 }

linq----Zip 扩展方法操作的对象是两个集合,它就像拉链一样,根据位置将两个系列中的每个元素依次配对在一起。其接收的参数是一个 Func 实例,该 Func 实例允许我们成对在处理两个集合中的元素。如果两个集合中的元素个数不相等,那么多出来的将会被忽略。

int[] numbers = { 3, 5, 7 };
string[] words = { "three", "five", "seven", "ignored" };
IEnumerable<string> zip = numbers.Zip(words, (n, w) => n + "=" + w);

foreach (string s in zip)
{
    Console.WriteLine(s);
}
result
3=three 5=five 7=seven

linq----OfType 用于筛选集合中指定类型的元素

linq----Cast 可以把集合转换为指定类型,但要求源类型必须可以隐式转换为目标类型

interface IFoo { }
class Foo : IFoo { }
class Bar : IFoo { }

var item0 = new Foo();
var item1 = new Foo();
var item2 = new Bar();
var item3 = new Bar();
var collection = new IFoo[] { item0, item1, item2, item3 };

var foos = collection.OfType<Foo>(); // result: item0, item1
var bars = collection.OfType<Bar>(); // result: item2, item3
var foosAndBars = collection.OfType<IFoo>(); // result: item0, item1, item2, item3

// 等同于使用 Where
var foos = collection.Where(item => item is Foo); // result: item0, item1
var bars = collection.Where(item => item is Bar); // result: item2, item3
var bars = collection.Cast<Bar>();  // InvalidCastException 异常
var foos = collection.Cast<Foo>();  // InvalidCastException 异常
var foosAndBars = collection.Cast<IFoo>();  // OK

linq----ToLookup扩展方法返回的是可索引查找的数据结构,它是一个 ILookup 实例,所有元素根据指定的键进行分组并可以按键进行索引

 string[] array = { "one", "two", "three" ,"1123"};
            // 根据元素字符串长度创建一个查找对象
            var lookup = array.ToLookup(item => item.Length);
            //Result:这个位置查询出来的事键值对形式,一个key对应多个value,key为字符长度,values为符合长度的字符
            // 查找字符串长度为 3 的元素
            var result = lookup[3];
            // result: one,two  

            int[] array1 = { 1, 2, 3, 4, 5, 6, 7, 8 };
            // 创建一个奇偶查找(键为 0 和 1)
            //太他娘抽象了 ,抽的我好难受
            var lookup1 = array1.ToLookup(item => item % 2);
            //result: 同上不好解释
            // 查找偶数
            var even = lookup1[0];
            // even: 2,4,6,8

            // 查找奇数
            var odd = lookup1[1];

Linq ----Distinct 去重高级 1.定义比较器,比较器里面可以添加验证的对象、

public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    public class IdEqualityComparer : IEqualityComparer<Person>
    {
        //这是判断的条件,默认验证所有的对象
        public bool Equals(Person x, Person y) => x.Id == y.Id && x.Name==y.Name;
        public int GetHashCode(Person p) => p.Id;
    }
    class Program
    {
        static void Main(string[] args)
        {
            var people = new List<Person>();
            people.Add(new Person() {Id=1,Name="张三"});
            people.Add(new Person() { Id = 1, Name = "张三" });
            people.Add(new Person() { Id = 0, Name = "lisai" });
            var distinct = people.Distinct(new IdEqualityComparer());
        }
    }

linq----Range

linq----Repeat

用于生成简单的数字或字符串系列。示例:

// 生成 1-100 的数字,即结果为 [1, 2, ..., 99, 100]
var range = Enumerable.Range(1, 100);

// 生成三个重复的字符串“a”,即结果为 ["a", "a", "a"]
var repeatedValues = Enumerable.Repeat("a", 3);

linq----Any

linq----All

Any 用来判断集合中是否存在任一一个元素符合条件,All 用来判断集合中是否所有元素符合条件。

var numbers = new int[] {1, 2, 3, 4, 5 };
bool result = numbers.Any(); // true
bool result = numbers.Any(x => x == 6); // false
bool result = numbers.All(x => x > 0); // true
bool result = numbers.All(x => x > 1); // false

linq----Concat

linq----Union

Concat 用来拼接两个集合,不会去除重复元素

Union 也是用来拼接两个集合,与 Concat 不同的是,它会去除重复项

List<int> foo = newList<int> { 1, 2, 3 };
List<int> bar = newList<int> { 3, 4, 5 };
// 通过 Enumerable 类的静态方法
var result = Enumerable.Concat(foo, bar).ToList(); // 1,2,3,3,4,5
// 通过扩展方法
var result = foo.Concat(bar).ToList(); // 1,2,3,3,4,5
var result = foo.Union(bar); // 1,2,3,4,5

linq----GroupBy分组 

扩展方法用来对集合进行分组,下面是一个根据奇偶进行分组的示例:

var list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var grouped = list.GroupBy(x => x % 2 == 0);
// grouped: [1, 3, 5, 7, 9] 和 [2, 4, 6, 8]

 linq----SequenceEqual 

SequenceEqual 扩展方法用于比较集合系列各个相同位置的元素是否相等

int[] a = new int[] {1, 2, 3};
int[] b = new int[] {1, 2, 3};
int[] c = new int[] {1, 3, 2};

bool result1 = a.SequenceEqual(b); // true
bool result2 = a.SequenceEqual(c); // false

 

posted @ 2020-08-05 13:17  人走茶亦凉  阅读(692)  评论(0编辑  收藏  举报