LINQ使用(一)

一、什么是LINQ

LINQ即 Language Integrated Query,语言集成查询,是微软新增的一种类似SQL查询数据库的方式的自然查询方法,是.net框架的扩展,查询时数据集时,非常方便,不用使用for/foreach循环遍历了

大约有40多个关键字帮助查询。
Where、Select、SelectMany、Skip、SkipWhile、Take、TakeWhile、Join、GroupJoin、Concate、OrderBy、OrderByDescending、ThenBy、ThenByDescending、Reverse、GroupBy、Distinct、Union、Intersect、Except、AsEnumerable、AsQueryable、ToArray、ToList、ToDictionary、ToLookup、OfType、Cast、SequenceEqual、First、FirstOrDefault、Last、LastOrDefault、Single、SingleOrDefault、ElementAt、ElementAtOrDefault、DefaultIfEmpty、All、Any、Contains、Count、LongCount、Sum、Min、Max、Average、Aggregate、equals/Equals、from/From、in/In、into/Into、key、let、Group、Range、Repeat。

二、如何使用LINQ

有两种方式,第一种,可以像SQL语句一样查询,也可以使用方法调用的方式查询。

 // LINQ Query
 //Method 1:
 var bmws = from Car in MyCars
            where Car.Make == "BMW"
            select Car;
//Method 2:
var bmws2 = MyCars.Where(p => p.Make == "BMW" && p.Year == 2018);

第二种p=>p.Make使用了lamda表达式,使语句更加简洁。

举个栗子:

  1. 定义1个Car类 class Car;
  2. 创建1个Car类的集合 List MyCars = new List();
  3. 通过LINQ进行查询、排序、判断、和输出。

以下是一些例子,可模仿一下。

class Program
 {
     class Car
     {
         public string Make;
         public int Year;
     }
     
     static void Main(string[] args)
     {
         List<Car> MyCars = new List<Car>();
         MyCars.Add(new Car() { Make = "BMW", Year = 2018 });
         MyCars.Add(new Car() { Make = "ZhongHua", Year = 2019 });
         MyCars.Add(new Car() { Make = "BMW", Year = 2019 });
         MyCars.Add(new Car() { Make = "BYD", Year = 2018 });
         MyCars.Add(new Car() { Make = "HongQi", Year = 2017 });

         // LINQ Query
         var bmws = from Car in MyCars
                    where Car.Make == "BMW"
                    select Car;

         var bmws2 = MyCars.Where(p => p.Make == "BMW" && p.Year == 2018);

         //SORT
         var orderedCars = from Car in MyCars
                           orderby Car.Year descending
                           select Car;

         var orderedCars2 = MyCars.OrderByDescending(p => p.Year);

         //choose first pick
         var firstCar = MyCars.First(p => p.Make == "BMW");
         //Order then choose the first
         var firstBMW = MyCars.OrderByDescending(p => p.Year).First(p => p.Make == "BMW");

         //print
         Console.WriteLine(MyCars.TrueForAll(p => p.Year > 2012));     //True

         MyCars.ForEach(p => Console.WriteLine("{0}{1:c}", p.Make, p.Year));  // BMW ¥2018.00...

         Console.WriteLine(MyCars.Exists(p => p.Make == "DaZhong"));  //false

         Console.WriteLine(MyCars.GetType());  // System.Collections.Generic.List`1[LINQ_Test.Program+Car]

         //caculate
         MyCars.ForEach(p => p.Year += 1);

         var newCars = from Car in MyCars
                       where Car.Make == "BMW"
                       && Car.Year == 2018
                       select new { Car.Make, Car.Year };
     }

 }

三、个人使用爱好

  1. Where中判断语句传入函数

LINQ中Where语句,可以看出来,里面其实是一个bool类型的判断,返回true or false。

所以,使用时不必拘泥与对数据集成员本身的判断,骚操作写入一个返回值为bool类型的函数,函数其中1个参数为数据集成员,如下所示,CheckHiddenPoint§函数就是对数据集对象进行处理,但是返回值为bool类型的,如此就可以避免采用for循环进行遍历了。

var checkEnts = listHiddenEntEx.AsParallel().Where(p =>CheckHiddenPoint(p)).ToList();
  1. 可以看到,linq支持并行处理,即多个成员同时进行判断处理,添加关键字.AsParallel.
//串行处理,1个接1个
var checkEnts = listHiddenEntEx.Where(p =>CheckHiddenPoint(p)).ToList();
//并行处理,加快处理速度。
var checkEnts = listHiddenEntEx.AsParallel().Where(p =>CheckHiddenPoint(p)).ToList();
  1. 使用并行计算时,如果要向同一个List集合中添加数据时,会造成两条数据同时向List中同一位置写入数据,会有资源争抢问题,会报访问index错误,并且并行过程中不可对写入的数据集进行Clear()操作,也会发生访问Index错误。未防止错误发生,可去掉并行处理。

一般不建议写入数据集过程中还要清理数据集的操作,会引发混乱。

如果单纯想并行写入同一个数据集,可采用lock的方法锁定数据集,每次只允许1个数据集写入数据。即可保证访问Index的正确性。

特别强调并行计算可以节约时间,但是加锁会减缓时间,让众多线程等待1个线程完成操作之后才能处理,所以到底是节约了时间没有,值得思考。

dic.AsParallel.Alll(p=>{AddRecord(p.Key,p.Value); return true;})
//声明公共数据集
List<string>() errorRecords = new List<string>();

public bool AddRecord(string A, string B){
	//干活
	lock (errorRecords)
	{
	 errorRecords.Add("发生错误"});
	}
}
  1. 两个数据集进行判断,采用SQL语句写。listWWTPEnt 与 listInAreaEnt 为2个List数据集,写2次from,即可以对两个数据集成员同时判断。

    该方法等效于for循环2次

  var listWSandPFK = from wwtp in listWWTPEnt
                     from inarea in listInAreaEnt
                     where isPfkInPsInArea(inarea, wwtp)
                     select new { inarea, wwtp };
  foreach (var item in listWSandPFK)
  {
	//干活
  }
//等效于for循环2次
  for (int i = 0; i < listInAreaEnt.Count; i++)
  {
      for (int j = 0; j < listPKEnt.Count; j++)
      {
          if (isPfkInPsInArea(listInAreaEnt[i], listPKEnt[j]))
          {
              //干活
          }
      }
  }
  1. 分组处理。有时候1个数据集需要根据成员属性进行分组,使用GroupBy关键字。
List<CommDB.CCommStruct.CheckCondition> listCheckCondition;
//干活

//按 应用图层和几何类型分组
   var checkGroups = listCheckCondition.GroupBy(p => new { p.yycm, p.jhlx }).ToList();  
    for (int i = 0; i < checkGroups.Count; i++)   //group.Key 为应用图层名
    {
    	string layer = checkGroups[i].Key.yycm;
    	string geoType = checkGroups[i].Key.jhlx
	List<CommDB.CCommStruct.CheckCondition> newGroupi = checkGroups[i];
	//干活
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值