基础数据搞一下
//先定义一个类
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(" " + 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