Where是条件帅选,返回一个IEnumerable<> 泛型接口集合,Select则是构建集合
参考资料:
Find和FirstOrDefault()有什么区别?
First,FirstOrDefault,Single,SingleOrDefault的区别
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace List泛型集合
{
class Program
{
static void Main(string[] args)
{
//ArrayList的好处是长度可变,可以往里面放任意类型的数据。但是当我们从ArrayList中取数据的时候,取出来的全部是Object类型的数据,最终还要将这个Object类型的数据转换成我们需要的类型数据。这期间就可以发生拆箱操作。费时间。而List泛型集合就能很好的解决这个问题。
//--------------------------------------Add(); AddRange()添加元素
//一旦你确定了泛型集合的类型,那么泛型集合里就只能存放该类型数据了。
//创建泛型集合对象
List list = new List();
list.Add(1); //单List的类型是int的时候。Add(int item) Add方法的参数是int类型的。说明只能网里面存int类型的数据
List listStr = new List();
listStr.Add("abc");//单List的类型是string的时候。Add(string item) Add方法的参数是string类型的。说明只能网里面存string类型的数据
List listArray = new List(); //list里面接收的是一个int[]数组。
listArray.Add(new int[] { 1, 2, 3 });
List listIEnumerable = new List();
//AddRange(IEnumerable collection); AddRange()方法的参数接收的是一个List的集合。
listIEnumerable.AddRange(new List() { new int[] { 1, 2, 3 }, new int[] { 4, 5, 6 } });
//--------------------------------------Insert() ;InsertRange()添加
List list1 = new List() { 1, 2, 3 };
list1.Insert(0, 5); //从list1这个泛型集合索引下标的0处插入一个5
//InsertRange(int Index, IEnumerable collection);注意括号中的第二个参数需要的是一个IEnumerable类型。根据里氏转换定律得知:一个地方需要一个父类,我们可以给它一个子类。因为List是继承自IEnumerable所以下面的参数是给了它一个List
list1.InsertRange(1, new List { 4, 5, 6 });//从listInt这个泛型集合索引下标的1处插入一个List集合
foreach (int i in list1)
{
Console.WriteLine(i); //输出5,1,2,3
}
//--------------------------------------Remove();RemoveRange()删除
List list2 = new List() { 1, 2, 3, 4, 5, 6, 7, 8 };
list2.Remove(1); //Remove(int item) 删除list2集合中 “1” 这个元素。
list2.RemoveAt(0);//RemoveAt(int index) 删除list2集合中索引下标为0的这个元素
list2.RemoveRange(0, 2);//RemoveRange(int index,int count) 删除一定范围内的元素。从索引下标0处开始删除,总共删除2个元素。
//RemoveAll(Predicate math) //接收的是一个拉姆达表达式
list2.RemoveAll(p => p > 2 && p <= 5); //删除list2集合中 大于2并且小于等于5之间的元素
foreach (int i in list2)
{
Console.WriteLine(i);
}
//--------------------------------------Clear()清空所有元素
List list3 = new List() { 1, 2, 3, 4, 5, 6 };
list3.Clear();
//--------------------------------------Contaion()包含
List list4 = new List() { 1, 2, 3, 4, 5, 6 };
bool b = list4.Contains(2); //Contains(int item) 检查list4泛型集合中是否包含了“2”这个元素。如果包含就返回true 不包含就返回false
//--------------------------------------First() Last();
List list5 = new List() { 1, 2, 3, 4, 5, 6 };
//假如list5这个泛型集合没有任何一项元素。那么调用First方法就会抛异常,提示:序列不包含任何元素
//First()方法的返回值为int类型。为什么是int类型?那是因为list5这个集合在什么的时候就已经确定它是一个int类型的泛型集合了List
int t1 = list5.First();//返回list5这个泛型集合中第一个元素 t1的值为1。假如当list5这个泛型集合没有包含任何元素的时候,即:
//List list5 = new List() { };
//int t1 = list5.First(); 这里会报错:提示:序列不包含任何元素
int t2 = list5.First(r => r > 4); //返回满足拉姆达表达式的第一个元素; list5中有5,6等元素是>4的,既然要返回满足条件的第一个元素。那么t2的值为5
//FindAll()方法返回值为一个List 泛型集合 。返回满足拉姆达表达式的所有元素
List t3 = list5.FindAll(r => r < 5); //t3的元素为 1,2,3,4
//Last():获取list5这个集合中的最后一个元素
int t4 = list5.Last();
Console.Write(t4); //输出6
//Last(r=>r<4):获取带筛选条件以后的新集合中的第最后一个元素
int t5=list5.Last(r=>r<4);
Console.Write(t5); //输出:3
//--------------------------------------Single();
List list6 = new List() { 1, 2, 3, 4, 5, 6 };
//如果集合没有任何元素,会抛异常,如果大于一个元素也会抛异常
//返回序列中满足指定条件的唯一元素;如果有多个这样的元素存在,则会引发异常
//int t4 = list6.Single(r => r > 3); //这里会抛异常,提示:序列包含一个以上的匹配元素。因为list6泛型集合里有4,5,6等多个元素是大于3的,不符合“唯一”的条件。(通俗的说:我要在list6这个集合中查找一个大于3的元素,并且我只要一个大于3的元素,如果你给我两个也不行,反正我只要一个。你给多了,或者一个都不给,我都会抛异常。)
//int t5 = list6.Single(r => r > 6);//这里会抛异常,提示:序列不包含任何匹配元素。(我要一个元素,可是你一个元素也没给我。我就抛异常了。)
int t6 = list6.Single(r => r > 5);//t6的值为6。 不会抛异常。因为list6泛型集合里只有,6等元素是大于5的。
//int t7 = list6.Single(); //会抛异常:提示:序列包含“一个以上”的匹配元素。
//如果 List list6 = new List() {1};
//int t7 = list6.Single();泛型集合里“有且只包含一个元素”的时候,调用Single()方法就不会抛异常了。
//--------------------------------------FirstOrDefault();
List list7 = new List() { 1, 2, 3, 4, 5, 6 };
//假如list7这个泛型集合没有任何一项元素,那么FirstOrDefault方法的默认返回值为0 而不会报错。(注:如果泛型集合的元素为空,FirstOrDefault方法的默认返回值是根据泛型的类型来定的。int类型的默认值就是0。string类型的默认值为null)
int tt1 = list7.FirstOrDefault(); //返回list7这个泛型集合中第一个元素 tt1的值为1。假如单list7这个泛型集合里没有任何元素的时候 ,即:
//List list7 = new List(){};
//int tt1 = list7.FirstOrDefault(); //tt1的值为默认为0 ;而不会报错。(这里之所以默认值为0是因为list7是一个int类型的泛型集合。而int的默认值就是0 如果list7是一个string类型的泛型集合的话。那么tt1的默认值就是null。因为string类型的默认值就是null)
//Console.WriteLine("tt1的值为{0}", tt1); //输出:tt1的值为0
int tt2 = list7.FirstOrDefault(r => r > 2); //返回满足括号中朗姆达表达式的第一个值:list7这个泛型集合中有3,4,5,6 等元素>2 ;所以既然是返回满足朗姆达表达式的第一个值。所以tt2的值为3
int tt3 = list7.FirstOrDefault(r => r == 8);
Console.WriteLine("tt3的值为", +tt3);//输出: tt3的值为___ 即:tt3的值为空 因为list7里没有8这个元素。所以找不到。既然找不到8这个元素,所以就什么都不会输出了。(注:这里tt3的值不是为0。而是为空)
//========================================================
//Find方法和FirstOrDefault方法效果相同,都是返回满足条件的第一个元素,如果没有该元素,则返回null。
//1>Find方法是.netFramework2.0的,而FirstOrDefault是3.5的。
//2>Find方法只能在List上使用,而后者能更广泛应用在IEnemerable上。
//>Find最终是建立在Array的查找之上,而在IEnemerable上的FirstOrDefault是使用foreach查找的。因此,Find速度会比FirstOrDefault快很多,据测试可能会快一倍以上。
//=========================================================
//--------------------------------------Find() FindAll();
List list8 = new List() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
//假如list8这个泛型集合没有任何一项元素。那么Find方法的默认值返回值为0 而不会报错。(注:如果泛型集合的元素为空,Find方法的默认返回值是根据泛型的类型来定的。int类型的默认值就是0。string类型的默认值为null)
int t8 = list8.Find(r => r < 6); //返回满足括号中朗姆达表达式的第一个元素 ;list8泛型集合中有1,2,3,4,5等元素是<6的 ,既然是返回满足朗姆达表达式的第一个值 所以:t8的值为1
int t9 = list8.Find(r => r > 6); //list8泛型集合中有7,8,9等元素的值是>6的。既然是返回满足朗姆达表达式的第一个值 所以:t9的值为7
List t10 = list8.FindAll(r => r > 2);//list8泛型集合中有3,4,5,6,7,8,9等元素的值是>2的。所有t10的元素为3,4,5,6,7,8,9
//我们来看看这个FindAll()方法为我们做的事情:1.遍历t10这个泛型集合,将集合中的每一项逐条传递到括号中的匿名委托中去,而匿名委托其实就是返回值是布尔类类型,参数是泛型类型的委托,具体请看最下面的FinAll()详解
//--------------------------------------Any() 只要有一个元素满足条件就返回true。否则返回false
List list9 = new List() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
//Any()检查list9泛型集合中的元素是否满足括号中的拉姆达表达式。只要有一个元素满足条件就返回true。否则返回false
bool b1 = list9.Any(r => r < 8); //b1的值为true;因为list9中有1,2,3,4,5,6,7等元素小于8
bool b2 = list9.Any(r => r > 8); //b2的值为true;因为list9中 元素9是大于8的
bool b3 = list9.Any(r => r > 10);//b3的值为false;因为list9中,没有任何一个元素大于10
//--------------------------------------All() 只有集合的“所有元素”都满足条件就返回true。否则返回false
List list10 = new List() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
bool b4 = list10.All(r => r > 5); // 因为list10这个泛型集合里有1,2,3,4等元素是<5的。没有达到达到所有元素都>5这个条件。所以b4的值为 false
bool b5 = list10.All(r => r < 10);//在list10这个泛型集合中,所有的元素都是<10的。所以b5的值为true
//--------------------------------------Where()
List list15 = new List() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var b6 = list15.Where(r => r > 6); //查询list15这个泛型集合中大于6的元素。注意这个Where的返回值是一个IEnumerable 泛型接口的集合
b6.ToList().ForEach(new Action(r=>Response.Write(r))); //将b6这个泛型接口集合转换成List集合,然后遍历,打印出: 7,8,9
var queryList = from item in list15
where (item > 5) //筛选出list15泛型集合中大于5的元素。
select (item);//将筛选出来的所以元素投影到新表中。即:根据where条件构建一个新的集合。
foreach (var item in queryList)
{
Response.Write(item); //输出6,7,8,9
}
//也可以这样遍历
queryList.ToList().ForEach(new Action(r => Response.Write(r))); //输出6,7,8,9
//--------------------------------------Exists() 是否包含与指定谓词所定义的条件相匹配的元素。如果包含就返回true。否则就返回false
List list16 = new List() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
bool b7 = list16.Exists(r => r > 5);//检查list16这个泛型集合中是否有 大于5的元素。因为list16泛型集合中有6,7,8,9等元素大于5所以 b7的值为true
//--------------------------------------ToArray() 将List泛型集合转换成数组
List list11 = new List() { 1, 2, 3, 4, 5, 6 };
int[] arr = list11.ToArray(); //将一个list 泛型集合转换成一个int类型的数组;这里可以转换是因为,List里存放的数据本身就是int类型的
//--------------------------------------ToList() 将数组转换成List泛型集合
int[] arr1 = new int[] { 1, 2, 3, 4, 5, 6 };
List list12 = arr1.ToList(); //将一个int[]类型数组转换成List泛型集合;这里可以转换是因为,List里存放的数据是int类型的。而arr数组存放的数据也是int 类型的
//--------------------------------------Reverse() 元素反转
List list13 = new List() { 1, 2, 8, 4, 5, 6 };
list13.Reverse(); //将list13这个泛型集合里的元素顺序反转。注意:是反转,不是降序排序
//--------------------------------------Sort() 升序排序
List list14 = new List() { 2, 8, 4, 1, 6, 5, 3, 7 };
list14.Sort(); //将list14这个泛型集合里的元素按照升序排序
Console.WriteLine("---------------");
foreach (int i in list14)
{
Console.WriteLine(i); //输出:1,2,3,4,5,6,7,8
}
//或者这样遍历list14这个集合
list14.ForEach(new Action(r => { Response.Write(r); })); //输出:1,2,3,4,5,6,7,8
//----------------------------------Count() 获取数据项数
List list17 = new List() { 2, 8, 4, 1, 6, 5, 3, 7 };
//Count()表示获取list17这个集合有几项数据
int a= list17.Count();
Console.Write(a); //输出:8
//Count(r => r > 5)表示获取满足筛选条件的数据总共有多少条
int b = list17.Count(r => r > 5);
Console.Write(b); //输出:3
Console.ReadKey();
}
}
}
class preson
{
public void Test()
{
var list = new List() //创建一个list泛型集合
{
new student{Name="张三",Age=15},
new student{Name="王五",Age=17}
};
Predicate pr = new Predicate(Pred); //pr是一个委托,这个委托指向pred方法; 这句也可以简写成:redicate pr=pred;
List b = list.FindAll(pr);
//这个FindAll 做的事情就是:1.遍历这个list集合 2.将list集合中的每一项逐条传递到 Pred这个方法中。例如:首先将new student{Name="张三",Age=15}这个对象传递到Pred方法中,因为这个对象的Age属性是15,它小于16,所以方法就会返回false,返回false的数据就会丢掉。接着会传递new student{Name="王五",Age=17} 这个对象到Pred这个方法中,因这个对象的Age属性是17,它大于16,所以方法会返回true,如果返回true,那么new student{Name="王五",Age=17}这条数据就会被返回,并保存到 b 这个泛型集合中去。3.最后b这个泛型集合里就保存了list中所有Age大于16的对象
}
public bool Pred(student stu)
{
return stu.Age > 16;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace 泛型
{
public class Studen
{
public string Name { get; set; }
public int Age { get; set; }
}
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var list=new List()
{
new Studen{Name="曹操",Age=46},
new Studen{Name="刘备",Age=52},
new Studen{Name="孙策",Age=18}
};
list.ForEach(new Action(r => { Response.Write(r.Name + r.Age); })); //打印出:曹操46 刘备52 孙策18
//其实这个ForEach,就是遍历了list这个集合。但是这个ForEach方法没有返回值。它仅仅是对list这个集合中的 内容进行处理,或打印
//在看下面这个例子:
List li = new List() { 0, 1, 2, 5, 4, 7 };
List result = new List();
li.ForEach(x => { x = x + 1; result.Add(x); }); //给li集合中每个元素加1,然后给加1后的值添加到result这个集合中去
result.ForEach(r => Response.Write(r));//遍历result这个集合。 输出:123658
}
}
}
特别要注意:组合排序的时候,对第一个字段排序的时候用OrderBy 或 OrderByDescending 对第第二个,及后面的排序要用ThenBy 或 ThenByDescending
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 泛型
{
public class Studen
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
List list18 = new List() { 2, 8, 4, 1, 6, 5, 3, 7 };
//正序排列
List a = list18.OrderBy(r => r).ToList(); //按照list18中的项排序。
a.ForEach(r => Console.WriteLine(r)); //输出:1,2,3,4,5,6,7,8
//倒序排序
//输出:8,7,6,5,4,3,2,1
list18.OrderByDescending(r => r).ToList().ForEach(r => Console.Write(r));
//-------------------例二
//根据年龄进行升序排列
var list = new List()
{
new Studen{Id=1, Name="曹操",Age=46},
new Studen{Id=2, Name="刘备",Age=52},
new Studen{Id=3, Name="孙策",Age=18},
new Studen{Id=4, Name="吕布",Age=52}
};
//我们看到OrderBy(Func keySelector) 它里面是一个带一个为Student类型的参数,返回值为Tkey的委托,以后当我们看到这个Tkey就应该要知道,这个Tkey就是表示从你的参数类型中取一个属性。 而这个参数是Student,从它里面去取一个属性。这里我们取的是Age这个属性。
//所以这里就是按照Student类中的Age属性来进行排序
var dd = list.OrderBy(r => r.Age).ToList();
//这里输出:孙策18 曹操46 刘备52 吕布52
dd.ForEach(r => Console.WriteLine(r.Name + r.Age));
Console.WriteLine();
//根据年龄进行倒序排列
//这里输出:刘备52 吕布52 曹操46 孙策18
list.OrderByDescending(r => r.Age).ToList().ForEach(r => Console.WriteLine(r.Name + r.Age));
Console.WriteLine();
//现在我们来看看多字段组合排序
//需求:先根据年龄进行升序排序,后再根据Id进行排序
//特别要注意:当使用组合排序的时候,第一个排序先使用OrderBy()或者OrderByDescending()进行排序。然后后面的排序,用ThenBy()或者ThenByDescending()进行排序
//例如:在先进行年龄排序的时候,我先用OrderBy()进行排序了。年龄排序完毕后,我再使用ThenBy()语句对Id进行排序。(ThenBy()也是排序的意思。)
list.OrderBy(r => r.Age).ThenBy(r => r.Id).ToList().ForEach(r => Console.WriteLine(r.Id + ":" + r.Name + ":" + r.Age));
//这里输出: 首先根据年龄进行升序排序了。然后我们对Id进行排序,因为吕布年龄和刘备年龄一样大,既然根据Id进行升序排序,刘备的Id是3,而吕布的Id是4 所以吕布就排在刘备的后面了。
//3:孙策:18
//1:曹操:46
//2:刘备:52
//4:吕布:52
Console.ReadKey();
}
}
}
排序
List list = new List() { "abc", "EDdeed", "eddeeeee", "DEFrr" };
var aa = (from item in list
where item.Length > 3
orderby item.Length ascending//descending
//orderby item.Length ascending, item.GetHashCode() descending 多字段排序(根据字符串的长度,和字符串的HashCode进行排序)
select item).ToList();
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 泛型
{
public class Studen
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
var list = new List()
{
new Studen{Id=1, Name="曹操",Age=46},
new Studen{Id=2, Name="刘备",Age=52},
new Studen{Id=3, Name="孙策",Age=18},
new Studen{Id=4, Name="吕布",Age=52}
};
//投影方法Select
//需求,从list集合中获取Id,和Name的值,以新的集合返回
//做法1
var a = list.Select(r => new Studen() { Id = r.Id, Name = r.Name }).ToList();
a.ForEach(r => Console.WriteLine( r.Id + ":" + r.Name));
//打印出:
//1:曹操
//2:刘备
//2:孙策
//4:吕布
//做法2 直接使用匿名类来接收
var b = list.Select(r => new { Id = r.Id, Name = r.Name }).ToList();
b.ForEach(r => Console.WriteLine(r.Id + ":" + r.Name));
//打印出:
//1:曹操
//2:刘备
//2:孙策
//4:吕布
//因为匿名类重写了ToString()方法,所以我们打印打印的时候可以这样写
b.ForEach(r => Console.WriteLine(r.ToString()));
//打印出:
//{Id=1, Name="曹操"}
//{Id=2, Name="刘备"}
//{Id=3, Name="孙策"}
//{Id=4, Name="吕布"}
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 泛型
{
public class Studen
{
public int Id { get; set; }
public int CountryId { get; set; } //做外键使用。与countrylist集合做连表使用的
public string Name { get; set; }
public int Age { get; set; }
}
public class Country
{
///
/// 国家编号
///
public int CountryId { get; set; }
///
/// 国家名字
///
public string CountryName { get; set; }
}
class Program
{
static void Main(string[] args)
{
//-----------分页(假分页)
var list = new List()
{
new Studen{Id=1, Name="曹操",Age=46,CountryId=1},
new Studen{Id=2, Name="刘备",Age=52,CountryId=2},
new Studen{Id=3, Name="孙策",Age=18,CountryId=3},
new Studen{Id=4, Name="曹植",Age=52,CountryId=1}
};
var countrylist = new List()
{
new Country{CountryId=1,CountryName="魏国"},
new Country{CountryId=2,CountryName="蜀国"},
new Country{CountryId=3,CountryName="吴国"},
};
//假如上面是两个表 :需求:获取学生的名称,和所属的国家,作为一个新的集合返回
//T-SQL:select s.Name,c.CountryName from list s inner join countrylist c on (s.CountryId=c.CountryId)
//第一个参数:表示list这个表要与哪个表进行连表查询。
//第二个参数和第三个参数:表示list集合的CountryId字段的值等于countrylist表的CountryId字段的值。用于连表
//第四个参数:s,c表示两个表,即list表和countrylist,然后从s表中取去Name字段,从c表中取出CountryName字段,然后组成一个新的集合返回
var newList = list.Join(countrylist, s => s.CountryId, c => c.CountryId, (s, c) => new { s.Name, c.CountryName }).ToList();
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 泛型
{
public class Studen
{
public int Id { get; set; }
public int CountryId { get; set; } //做外键使用。与countrylist集合做连表使用的
public string Name { get; set; }
public int Age { get; set; }
}
public class Country
{
///
/// 国家编号
///
public int CountryId { get; set; }
///
/// 国家名字
///
public string CountryName { get; set; }
}
class Program
{
static void Main(string[] args)
{
//-----------分页(假分页)
var list = new List()
{
new Studen{Id=1, Name="曹操",Age=46,CountryId=1},
new Studen{Id=2, Name="刘备",Age=52,CountryId=2},
new Studen{Id=3, Name="孙策",Age=18,CountryId=3},
new Studen{Id=4, Name="曹植",Age=52,CountryId=1}
};
//需求:将list按照CountryId字段进行分组 (魏国有2个人,吴国和蜀国都是一个人,所以这里应该是分成了3组。)
//根据list集合中的Id来进行分组,然后就获取到了分组后的集合
var grouedList = list.GroupBy(s => s.CountryId).ToList();
//那我们想知道这个grouedList到底有几组数据。怎么做呢?
grouedList.ForEach(r => Console.WriteLine("分组号:"+r.Key)); //这个r.key就是每个分组的序列号
//打印出:
//分组号:1
//分组号:2
//分组号:3
//或者这样就可以直接打印出到底分了几组
Console.WriteLine(grouedList.Count()); //打印出:3
//现在我们要查看每组的内容怎么看呢?
grouedList.ForEach(a =>
{
Console.WriteLine("--------分组号:" + a.Key+"--------");
a.ToList().ForEach(b => Console.WriteLine(b.Id + "-" + b.Name + "-" + b.Age + "-" + b.CountryId));
});
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 泛型
{
public class Studen
{
public int Id { get; set; }
public int CountryId { get; set; } //做外键使用。与countrylist集合做连表使用的
public string Name { get; set; }
public int Age { get; set; }
}
public class Country
{
///
/// 国家编号
///
public int CountryId { get; set; }
///
/// 国家名字
///
public string CountryName { get; set; }
}
class Program
{
static void Main(string[] args)
{
//-----------分页(假分页)
var list = new List()
{
new Studen{Id=1, Name="曹操",Age=46,CountryId=1},
new Studen{Id=2, Name="刘备",Age=52,CountryId=2},
new Studen{Id=3, Name="孙策",Age=18,CountryId=3},
new Studen{Id=4, Name="曹植",Age=52,CountryId=1}
};
//var countrylist = new List()
//{
// new Country{CountryId=1,CountryName="魏国"},
// new Country{CountryId=2,CountryName="蜀国"},
// new Country{CountryId=3,CountryName="吴国"},
//};
//需求: 将从list集合中查找出来的CountryId=1的集合
//T-SQL:select * from list s where s.CountryId=1
//将它翻译成Linq语法
//语句以from 开始,然后先取个别名,别名就叫s ,这个别名是谁的别名呢? in list 就表示这个别名是list的别名。
//所以from s in list 就相当于t-sql中的 from list
var a = (from s in list
//现在开始带条件了, where就是条件语句。
//所以where s.CountryId==1 就相当于t-sql中的where s.CountryId=1
where s.CountryId == 1
//最后就差t-sql语句中的select 了。而 select s 这个s其实就是相当于list集合中的所有的元素,所以select s 就相当于t-sql语句中的select *
select s).ToList();
//需求:从list集合中找出CountryId=1的集合中的Nmae属性的值,然后以新的集合返回
var b =( from s in list
where s.CountryId == 1
select new { s.Name ,s.CountryId}).ToList();
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Linq排序
{
public class Studen
{
public int Id { get; set; }
public int CountryId { get; set; } //做外键使用。与countrylist集合做连表使用的
public string Name { get; set; }
public int Age { get; set; }
}
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var list = new List()
{
new Studen{Id=1, Name="曹操",Age=46,CountryId=1},
new Studen{Id=2, Name="刘备",Age=52,CountryId=2},
new Studen{Id=3, Name="孙策",Age=18,CountryId=3},
new Studen{Id=4, Name="曹植",Age=52,CountryId=1}
};
//将list集合按照年龄进行排序
var queryList = (from f in list
orderby f.Age descending //descending就表示根据年龄进行倒序排序,如果想进行升序排序可以用ascending关键字。如果不加关键字默认就是升序排序
select (f)).ToList();
//queryList.ForEach(r => Response.Write("Id=" + r.Id + " Name=" + r.Name + " Age=" + r.Age + " CountryId=" + r.CountryId+"
"));
//输出:
//Id=2 Name=刘备 Age=52 CountryId=2
//Id=4 Name=曹植 Age=52 CountryId=1
//Id=1 Name=曹操 Age=46 CountryId=1
//Id=3 Name=孙策 Age=18 CountryId=3
//Linq进行多字段组合排序
//需求: 将list集合按照年龄进行升序排序,然后按照Id进行降序排序
var qList = (from f in list
orderby f.Age ascending,f.Id descending
select (f)).ToList();
qList.ForEach(r => Response.Write("Id=" + r.Id + " Name=" + r.Name + " Age=" + r.Age + " CountryId=" + r.CountryId + "
"));
//输出
//Id=3 Name=孙策 Age=18 CountryId=3
//Id=1 Name=曹操 Age=46 CountryId=1
//Id=4 Name=曹植 Age=52 CountryId=1 //在年龄都是一样的情况下,Id是降序排序的,所以Id=4的这条数据排在前面
//Id=2 Name=刘备 Age=52 CountryId=2
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Linq连表操作
{
public class Studen
{
public int Id { get; set; }
public int CountryId { get; set; } //做外键使用。与countrylist集合做连表使用的
public string Name { get; set; }
public int Age { get; set; }
}
public class Country
{
///
/// 国家编号
///
public int CountryId { get; set; }
///
/// 国家名字
///
public string CountryName { get; set; }
}
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var list = new List()
{
new Studen{Id=1, Name="曹操",Age=46,CountryId=1},
new Studen{Id=2, Name="刘备",Age=52,CountryId=2},
new Studen{Id=3, Name="孙策",Age=18,CountryId=3},
new Studen{Id=4, Name="曹植",Age=52,CountryId=1},
new Studen{Id=5, Name="吕布",Age=56,CountryId=4}
};
var countrylist = new List()
{
new Country{CountryId=1,CountryName="魏国"},
new Country{CountryId=2,CountryName="蜀国"},
new Country{CountryId=3,CountryName="吴国"},
};
//内连接 inner join
var queryList = (from l in list
join c in countrylist
on l.CountryId equals c.CountryId
select new { l.Id, l.Name, c.CountryName }).ToList();
queryList.ForEach(r => Response.Write("Id=" + r.Id + " Name=" + r.Name + " CountryName=" + r.CountryName + "
"));
//输出:
//Id=1 Name=曹操 CountryName=魏国
//Id=2 Name=刘备 CountryName=蜀国
//Id=3 Name=孙策 CountryName=吴国
//Id=4 Name=曹植 CountryName=魏国
//外连接 (很少用,不是重点)
var qList = (from l in list
join c in countrylist.DefaultIfEmpty()
on l.CountryId equals c.CountryId into lc //这个lc其实就是countrylist集合的临时标识
//from s in lc.DefaultIfEmpty(new Country() { CountryId = 0, CountryName = "未知" })
from s in lc.DefaultIfEmpty() //DefaultIfEmpty:表示返回指定序列的元素;如果序列为空,则返回单一实例集合中的类型参数的默认值,例如 int默认值就是0 string 默认值就是 null (我的理解就是:list是左表,countrylist是右表,如果左表有5条数据,它根据CountryId这个字段连接右表后,因为左表有CountryId=4这条数据,而右表没有CountryId=4的这条数据,此时左表的数据应该全部显示,而右表没有CountryId=4的这条数据,应该显示为未知)
select new
{
l.Id,
l.Name,
HH = s == null ? "未知" : s.CountryName //因为右表没有CountryId=4的这条数据,所以在外连接查询的过程中,做表对应的某条数据,在又表中可能不存在,即左表有CountryId=4的这条数据,而右表中CountryId=4的这条数据可能不存在。这样就出现这条数据为null。因为在匿名类中,null是无法作为匿名类属性的值的。所以如果右表中的某条数据如果不存在,即为null的情况下,我们应该给它赋初始值,所以这里就出现了当s==null的时候,我们就给它赋“未知”这个初始值,如果不为null的话,就给它赋s.CountryName这个值。当然如果不想在这里写这个三元运算符判断的话,也可以在from这条语句这里这么写:from s in lc.DefaultIfEmpty(new Country() { CountryId = 0, CountryName = "未知" })
}).ToList();
qList.ForEach(r => Response.Write("Id=" + r.Id + " Name=" + r.Name + " CountryName=" + r.HH + "
"));
//Id=1 Name=曹操 CountryName=魏国
//Id=2 Name=刘备 CountryName=蜀国
//Id=3 Name=孙策 CountryName=吴国
//Id=4 Name=曹植 CountryName=魏国
//Id=5 Name=吕布 CountryName=未知
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Linq分组查询
{
public class Studen
{
public int Id { get; set; }
public int CountryId { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var list = new List()
{
new Studen{Id=1, Name="曹操",Age=46,CountryId=1},
new Studen{Id=2, Name="刘备",Age=52,CountryId=2},
new Studen{Id=3, Name="孙策",Age=18,CountryId=3},
new Studen{Id=4, Name="曹植",Age=52,CountryId=1},
new Studen{Id=5, Name="吕布",Age=56,CountryId=4}
};
//需求:从list集合中查询CountryId=1的集合
var queryList = (from c in list
group c by c.CountryId).ToList();
//Response.Write("根据CountryId这个字段来分组,总共分了" + queryList.Count() + "组"); //这里输出:根据CountryId这个字段来分组,总共分了4组
//然后我们来看看这4组中 具体有哪些值
queryList.ForEach(r=>{ Response.Write("--------------第"+r.Key+"组-----------
");
r.ToList().ForEach(c => Response.Write("Id=" + c.Id + " Name=" + c.Name + " Age=" + c.Age + " CountryId=" + c.CountryId + "
"));
});
//打印出:
//--------------第1组-----------
//Id=1 Name=曹操 Age=46 CountryId=1
//Id=4 Name=曹植 Age=52 CountryId=1
//--------------第2组-----------
//Id=2 Name=刘备 Age=52 CountryId=2
//--------------第3组-----------
//Id=3 Name=孙策 Age=18 CountryId=3
//--------------第4组-----------
//Id=5 Name=吕布 Age=56 CountryId=4
}
}
}
//根据keyword进行分组,然后取AddTime最大的那条数据
var aa = sa.UserKeyword.GroupBy(r => r.Keyword).Select(
a => (new { name = a.Key, count = a.Count(),addtime= a.Max(i=>i.AddTime),result=a })
).ToList();
//GroupBy(r=>new{r.UserId,r.Keyword})表示根据UserId和Keyword两个字段来分组
var bb = sa.UserKeyword.GroupBy(r => new {r.UserId,r.Keyword }).Select(
a => (new {name = a.Key, count = a.Count(), addtime = a.Max(i => i.AddTime) })
).ToList();
例子
public class HomeController : Controller
{
public ActionResult Index()
{
List list = new List()
{
new Student{ Id=1, Name="张三", UserId=11, AddTime=Convert.ToDateTime("2016-10-12")},
new Student{ Id=2, Name="李四", UserId=22, AddTime=Convert.ToDateTime("2016-10-13")},
new Student{ Id=3, Name="李四", UserId=22, AddTime=Convert.ToDateTime("2016-10-11")},
new Student{ Id=4, Name="王五", UserId=33, AddTime=Convert.ToDateTime("2016-10-14")},
};
var items = (from s in list
group s by new { s.Name, s.UserId } into t //根据Name和UserId进行分组
select new
{
name = t.Key,
maxTime = t.Max(r => r.AddTime), //取最大时间的那条数据
result = t.ToList() //这个result中包含了Id,Name,UserId,AddTime信息
}).ToList();
List listB = new List();
foreach (var item in items)
{
var student=new Student();
student.Id=item.result.FirstOrDefault(r=>r.AddTime==item.maxTime).Id;
student.Name=item.result.FirstOrDefault().Name;
student.UserId=item.result.FirstOrDefault().UserId;
student.AddTime=item.maxTime;
listB.Add(student);
};
return View();
}
}
public class Student
{
public int Id { get; set; }
public int UserId { get; set; }
public string Name { get; set; }
public DateTime AddTime { get; set; }
}