iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >c#中的LINQ怎么使用
  • 210
分享到

c#中的LINQ怎么使用

2023-06-30 01:06:27 210人浏览 八月长安
摘要

这篇文章主要介绍“C#中的LINQ怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“c#中的LINQ怎么使用”文章能帮助大家解决问题。一.并行LINQSystem.Linq名称空间中包含的类Pa

这篇文章主要介绍“C#中的LINQ怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“c#中的LINQ怎么使用”文章能帮助大家解决问题。

一.并行LINQ

System.Linq名称空间中包含的类ParallelEnumerable可以分解查询的工作,使其分布在多个线程上。
尽管Enumerable类给IEnumerable<T>接口定义了扩展方法,但ParallelEnumerable类的大多数扩展方法是ParallerQuery<TSource>类的扩展。例如,AsParallel()方法,它扩展了IEnumerable<T>接口,返回ParallelQuery<T>类,所以正常的集合类可以以平行方式查询。

1.并行查询

下面演示并行LINQ(Parallel LINQ,PLINQ):

//用随机值填充一个大型的int集合        // Enumerable.Range(0, arraySize),生成指定范围内的整数的空序列。        //Select(x => r.Next(140)),用小于140的数填充集合        static IEnumerable<int> SampleData()        {          const int arraySize = 100000000;          var r = new Random();          return Enumerable.Range(0, arraySize).Select(x => r.Next(140)).ToList();        }        static void IntroParallel()        {          var data = SampleData();          var watch = new Stopwatch();        //非并行LINQ          watch.Start();          var q1 = (from x in data                    where Math.Log(x) < 4                    select x).Average();          watch.Stop();          Console.WriteLine("sync {0}, result: {1}", watch.ElapsedMilliseconds, q1);          watch.Reset();                    //使用data.AsParallel()进行并行LINQ          watch.Start();          var q2 = (from x in data.AsParallel()                where Math.Log(x) < 4                select x).Average();          watch.Stop();          Console.WriteLine("async {0}, result: {1}", watch.ElapsedMilliseconds, q2);        }

输出;

c#中的LINQ怎么使用

发现并行查询时间用的少,在并行查询时CPU利用率达到100%
与LINQ基础(二)(https://www.yisu.com/article/244215.htm)中的LINQ查询一样,编译器会修改语法,以调用AsParallel,Where(),Select(),Average()方法:

  var q2 = data.AsParallel().Where(x => Math.Log(x)<4).Select(x => x).Average();

AsParallel()方法用ParallerEnumerable类定义,以扩展IEnumerable<T>接口,所以可以对简单的数组调用它。AsParallel()方法返回ParallerQuery<T>。因为返回的类型,所以编译器选择的Where()方法是ParallerEnumerable.Where(),而不是Enumerable.Where()。
对于PrarllelEnumerable类,查询是分区的,以便多个线程可以同时处理该查询。集合可以分为多个部分,其中每个部分由不同的线程处理。完成分区的工作后,就需要合并,获得所有部分的总和。

2.分区器

AsParallel()方法不仅扩展了IEnumerable<T>接口,还扩展了Partitioner类。通过它可以影响要创建的分区。
Partitioner类用System,Collection.Concurrent名称空间定义,并且有不同的变体。Create()方法接受实现了IList<T>类的数组或对象,以及Boolean类型的参数,返回一个不同的Partitioner类型。Create()方法有多个重载版本。

    var q2 = (from x in Partitioner.Create(data).AsParallel()      where Math.Log(x) < 4        select x).Average();

也可以对AsParallel()方法接着调用WithExecutionMode()和WithDegreeOfParallelism()方法,来影响并行机制。WithExecutionMode()方法可以传递ParallelExecutionMode的一个Default值或者ForceParallelism值。默认情况下,并行LINQ避免使用系统开销很高的并行机制。WithDegreeOfParallelism()方法,可以传递一个整数值,以指定应并行运行的最大任务数。如果查询不应使用全部CPU,这个方法很有用。

3.取消

要取消长时间运行的查询,可以给查询添加WithCancellation()方法,并传递一个CancellationToken令牌作为参数。CancellationToken令牌从CancellationTokenSource类中创建。
举个例子,下面的查询在单独的线程中运行,如果取消了查询,在该线程中捕获一个OperationCanceledException类型的异常。在主线程中,可以调用CancellationTokenSource类的Cancle()方法取消任务。

var data = SampleData();          var watch = new Stopwatch();          watch.Start();          Console.WriteLine("filled array");          var sum1 = (from x in data                      where Math.Log(x) < 4                      select x).Average();          Console.WriteLine("sync result {0}", sum1);          var cts = new CancellationTokenSource();                    Task.Factory.StartNew(() =>            {              try              {                var res = (from x in data.AsParallel().WithCancellation(cts.Token)                           where Math.Log(x) < 4                           select x).Average();                Console.WriteLine("query finished, result: {0}", res);              }              catch (OperationCanceledException ex)              {                Console.WriteLine(ex.Message);              }            });          watch.Stop();          Console.WriteLine("async {0}, result: {1}", watch.ElapsedMilliseconds, "res");          Console.WriteLine("query started");          Console.Write("cancel? ");          string input = Console.ReadLine();          if (input.ToLower().Equals("y"))          {              cts.Cancel();              Console.WriteLine("sent a cancel");          }          Console.WriteLine("press return to exit");          Console.ReadLine();

二.表达式树

在LINQ To Object 中,扩展方法需要将一个委托类型作为参数,这样就可以将lambda表达式赋予参数。lambda表达式也可以赋予Expression<T>类型的参数,C#编译器根据类型给lambda表达式定义不同的行为。如果类型是Expression<T>,编译器就从lambda表达式中创建一个表达式树,并存储在程序集中。这样就可以在运行期间分析表达式树,并进行优化,以便查询数据源。

  var racers = from r in FORMula1.GetChampions()    where r.Wins > 15 && (r.Country == "Brazil" || r.Country == "Austria")      select r;

这个查询表达式使用了扩展方法Where(),Select()方法。Enumerable类定义了Where()方法,并将委托类型Func<T,bool>作为参数谓词:

  public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,Func<TSource,bool> predicate);

这样,就可以把lambda表达式赋予委托predicate。
除了使用委托之外,编译器还会把表达式树放在程序集中。表达式树可以在运行期间读取。表达式树从派生自抽象基类Expression的类中构建。Expression和Expression<T>不同。继承自Expression类的表达式类有BinaryExpression,ConstantExpression,InvocationExpression等。编译器会从lambda表达式中创建表达式树。
例如,lambda表达式r.Country == "Brazil"使用了ParameterExpression,MemberExpression,ConstantExpression,MethodCallExpression,来创建一个表达式树,并将该树存储在程序集中,之后在运行期间使用这个树,创建一个用于底层数据源的优化查询:

//DisplayTree方法在控制台上图形化的显示表达式树。其中传递一个Expression对象,并根据表达式的类型,把表达式的一些信息写到控制台上                private static void DisplayTree(int indent, string message, Expression expression)                {                    string output = String.Format("{0} {1} ! nodeType: {2}; Expr: {3} ",                          "".PadLeft(indent, '>'), message, expression.NodeType, expression);                    indent++;                    switch (expression.NodeType)                    {                        case ExpressionType.Lambda:                            Console.WriteLine(output);                            LambdaExpression lambdaExpr = (LambdaExpression)expression;                            foreach (var parameter in lambdaExpr.Parameters)                            {                                DisplayTree(indent, "Parameter", parameter);                            }                            DisplayTree(indent, "Body", lambdaExpr.Body);                            break;                        case ExpressionType.Constant:                            ConstantExpression constExpr = (ConstantExpression)expression;                            Console.WriteLine("{0} Const Value: {1}", output, constExpr.Value);                            break;                        case ExpressionType.Parameter:                            ParameterExpression paramExpr = (ParameterExpression)expression;                            Console.WriteLine("{0} Param Type: {1}", output, paramExpr.Type.Name);                            break;                        case ExpressionType.Equal:                        case ExpressionType.AndAlso:                        case ExpressionType.GreaterThan:                            BinaryExpression binExpr = (BinaryExpression)expression;                            if (binExpr.Method != null)                            {                                Console.WriteLine("{0} Method: {1}", output, binExpr.Method.Name);                            }                            else                            {                                Console.WriteLine(output);                            }                            DisplayTree(indent, "Left", binExpr.Left);                            DisplayTree(indent, "Right", binExpr.Right);                            break;                        case ExpressionType.MemberAccess:                            MemberExpression memberExpr = (MemberExpression)expression;                            Console.WriteLine("{0} Member Name: {1}, Type: {2}", output,                               memberExpr.Member.Name, memberExpr.Type.Name);                            DisplayTree(indent, "Member Expr", memberExpr.Expression);                            break;                        default:                            Console.WriteLine();                            Console.WriteLine("{0} {1}", expression.NodeType, expression.Type.Name);                            break;                    }                }                static void Main()                {                    Expression<Func<Racer, bool>> expression = r => r.Country == "Brazil" && r.Wins > 6;                    DisplayTree(0, "Lambda", expression);                }

输出:

c#中的LINQ怎么使用

使用Expression<T>类型的一个例子是ADO.net EF 和WCF数据服务的客户端提供程序。这些技术用Expression<T>参数定义了扩展方法。这样,访问数据库的LINQ提供程序就可以读取表达式,创建一个运行期间优化的查询,从数据库中获取数据。
后面会单独介绍表达式树的使用。

三.LINQ提供程序

.NET包含几个LINQ提供程序。LINQ提供程序为特定的数据源实现了标准的查询操作符。LINQ提供程序也许会实现比LINQ定义的更多扩展方法,但至少要实现标准操作符。LINQ To XML实现了一些专门用于XML的方法,后面会详细介绍。
LINQ提供程序的实现方案是根据名称空间和第一个参数的类型来选择的。实现扩展方法的类的名称空间必须是开放的,否则扩展方法就不在作用域内。在LINQ to Objects中定义的Where()方法的参数和LINQ To Entities中定义的Where()方法的参数不同:
LINQ to Objects中定义的Where()方法:

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,Func<TSource,bool> predicate);

LINQ To Entities中定义的Where()方法:

public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source,Expression<Func<TSource,bool>> predicate);

这两个类都在System.Linq的Syste,.Core程序集中实现。无论是用Func<TSource,bool>传递参数,还是用Expression<Func<TSource,bool>>参数传递,lambda表达式都相同。只是编译器的行为不同,它根据source参数来选择。编译器根据其参数选择最匹配的方法。在ADO.NET EF中定义的ObjectContext类CreateQuery<T>()方法返回一个实现了IQueryable<TSource>接口的ObjectQuery<T>对象,因此EF使用Querable类的Where()方法。

关于“c#中的LINQ怎么使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网精选频道,小编每天都会为大家更新不同的知识点。

--结束END--

本文标题: c#中的LINQ怎么使用

本文链接: https://www.lsjlt.com/news/326930.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • c#中的LINQ怎么使用
    这篇文章主要介绍“c#中的LINQ怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“c#中的LINQ怎么使用”文章能帮助大家解决问题。一.并行LINQSystem.Linq名称空间中包含的类Pa...
    99+
    2023-06-30
  • 怎么在c#中使用Linq查询语句
    怎么在c#中使用Linq查询语句?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Lambda表达式简介:      &...
    99+
    2023-06-14
  • LINQ中的关键字怎么使用
    这篇文章主要讲解了“LINQ中的关键字怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“LINQ中的关键字怎么使用”吧!什么是LINQLINQ是Language Integrated Q...
    99+
    2023-06-17
  • C#中LINQ的用途是什么
    LINQ(Language Integrated Query)是C#中的一种功能,它允许开发人员使用类似SQL的查询语法来查询各种数...
    99+
    2024-04-03
    LINQ
  • c#中LINQ的基本使用方法是什么
    今天小编给大家分享一下c#中LINQ的基本使用方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1.筛选LINQ查询使...
    99+
    2023-06-30
  • LINQ的Customers类怎么使用
    本篇内容介绍了“LINQ的Customers类怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!LINQ 究竟是什么?LINQ,全名叫 ...
    99+
    2023-06-17
  • C#中如何使用LINQ查询数据
    C#中如何使用LINQ查询数据,需要具体代码示例LINQ(Language Integrated Query)是C#中的一种强大的查询语言,它可以帮助开发者简化对数据的查询和操作。本文将介绍如何在C#中使用LINQ查询数据,并提供具体的代码...
    99+
    2023-10-22
    C# 查询数据 C#中的关键词: LINQ
  • LINQ To XML怎么使用
    这篇文章主要讲解了“LINQ To XML怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“LINQ To XML怎么使用”吧!LINQ To XML——XML操作XML数据越来越广泛地...
    99+
    2023-06-17
  • c#中linq的用途有哪些
    在C#中,LINQ(Language Integrated Query)被广泛应用于查询和操作各种数据源,包括但不限于: 查询集合...
    99+
    2024-03-11
    c# linq
  • LINQ中LINQPad怎么用
    小编给大家分享一下LINQ中LINQPad怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!LINQPad支持C# 3.0 和 Framework 3.5的全部...
    99+
    2023-06-18
  • LINQ Customers类怎么使用
    本篇内容介绍了“LINQ Customers类怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!建立dbml(Database Mark...
    99+
    2023-06-17
  • c#中LINQ的基本用法(三)
    一.并行LINQ System.Linq名称空间中包含的类ParallelEnumerable可以分解查询的工作,使其分布在多个线程上。尽管Enumerable类给IEnumerab...
    99+
    2024-04-02
  • LINQ查询怎么使用
    本篇内容主要讲解“LINQ查询怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“LINQ查询怎么使用”吧!LINQ是Visual Studio 2008及其以后版本中提供的功能,将强大的查询...
    99+
    2023-06-17
  • LINQ嵌套怎么使用
    这篇文章主要介绍“LINQ嵌套怎么使用”,在日常操作中,相信很多人在LINQ嵌套怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”LINQ嵌套怎么使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!LI...
    99+
    2023-06-17
  • c#中LINQ的基本用法(一)
    LINQ(Language Integrated Query,语言集成查询),在C#语言中集成了查询语法,可以用相同的语法访问不同的数据源。LINQ提供了不同数据源的抽象层,所以可以...
    99+
    2024-04-02
  • c#中LINQ的基本用法(二)
    目录1.筛选2.用索引筛选3.类型筛选4.复合的from子句5.排序6.分组7.对嵌套的对象分组8.内连接9.左连接10.组连接11.集合操作12.合并13.分区14.聚合操作符15...
    99+
    2024-04-02
  • Linq Select子句怎么使用
    本篇内容主要讲解“Linq Select子句怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Linq Select子句怎么使用”吧!选择数据(SELECT)Linq Select...
    99+
    2023-06-17
  • C#中的Linq To XML讲解
    一、概述 Overview - LINQ to XML | Microsoft 官方文档 LINQ to XMLLINQ to XML 是一种启用了 LINQ 的内存 XML 编程接...
    99+
    2024-04-02
  • java中linq的使用方法是什么
    在Java中,没有内置的LINQ(Language Integrated Query)语法,但可以使用第三方库,比如Stream A...
    99+
    2024-04-03
    Java linq
  • LINQ是什么及怎么使用
    本文小编为大家详细介绍“LINQ是什么及怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“LINQ是什么及怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、为什么要使用LINQ要理解为什么使用LIN...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作