LINQ统一数据操作语句
来源:互联网 发布:centos 6.5配置双ip 编辑:程序博客网 时间:2024/05/08 03:36
一、基本原理
2.用了拓展方法,在generic枚举类型来做,编译器会将LINQ语句解释为where上的枚举类型的事例对象上调用拓展方法,实现功能。因为拓展方法的拓展接口是IEnumerable所以所有继承该接口的实现类都支持该拓展方法。
不是所有的数据筛选都可以用预定义的拓展方法LINQ来表示,所以有时候要自己定义LINQ函数和拓展方法;拓展方法工作方式是直接from r in语句活得数据源结构对象集合调用where方法,返回结果集再调用select或者group方法;LINQ运算顺序都是从左到右的,如果嵌套的from语句那么外部和内部将有两个传入参数作为selectmany的输入,提供一个内部的类型作为约束,外部的类型输出和继续使用后面的约束。
3. 用了枚举器来做,LINQ只是定义遇到yield return标记返回不执行,foreach才执行yield return执行下去,转换为其它容器或ToLookup时候会立即执行。但是注意中间数据结构元素的变化会迭代出不同的结果,如果最后用了Tolist等就不会等到迭代时才返回集合。
LINQ上的操作,where选定数据集,数据查找筛选,逻辑表达式和比较表达式支持,开始偏移和截取长度搜索个数,前面开始后面开始搜索,排序,分组,数据连接外部内部,集合操作,聚合函数,视图集合转换产生,判断是否满足条件的函数。
2).排序orderby语句,以及和 thenby多个组合语句。
3).分组group,group r by r.x into 别名 。是用groupby拓展方法来进行分组。
select new可以从分组的结果里面再创建新的统计结果。
4).连接jiont操作
5).集合操作交并差,可以将查询语句封装为方法或limban表达式.
二、LINQ数据处理应用
1).筛选from 嵌套from2).排序orderby语句,以及和 thenby多个组合语句。
3).分组group,group r by r.x into 别名 。是用groupby拓展方法来进行分组。
select new可以从分组的结果里面再创建新的统计结果。
4).连接jiont操作
5).集合操作交并差,可以将查询语句封装为方法或limban表达式.
6).zip(),take(),skip()方法。
7).聚合函数
8).转换为其它容器, 查询会在迭代时候执行,而转换为容器时候却会立即执行。
7).聚合函数
8).转换为其它容器, 查询会在迭代时候执行,而转换为容器时候却会立即执行。
ToLookup函数和非类型化的集合上使用LINQ就可以用Cast()方法作为转换。
9)Range,Empty,Repeat()不是拓展方法,而是集合类的正常静态方法,也会推迟执行,基于原来类型构建迭代器。
具体多查询资料和实践编程。
三、并行查询
在.net 4.0后增加的,通过System.Linq中的新类,ParallelEnumerable可以分解查询工作到多个线程中,ParallelEnumerable大多数拓展方法是ParallelQuery<TSource>的拓展,一个例外是AsParallel()方法它拓展了IEnumerable<TSource>接口,返回ParallelQuery<TSource>类,所以正常集合可以并行方式查询。
应用:1)正常查询用容器上containerName.AsParallel()方法,那么所有的where,select,sum都会变成Parallel版本的。
2)Partitioner.Create(containerName,true).AsParallel()来并行查询。
3)取消,调用WithCancellation方法,且传递一个CancellationToken作为令牌参数创建,需要调用时候用令牌Cancel()就可以了,例如:
例如:
static void Main() { // IntroParallel(); Cancellation(); } static void Cancellation() { const int arraySize = 100000000; var data = new int[arraySize]; var r = new Random(); for (int i = 0; i < arraySize; i++) { data[i] = r.Next(40); } var cts = new CancellationTokenSource(); new Thread(() => { try { var sum = (from x in data.AsParallel().WithCancellation(cts.Token) where x < 80 select x).Sum(); Console.WriteLine("query finished, sum: {0}", sum); } catch (OperationCanceledException ex) { Console.WriteLine(ex.Message); } }).Start(); Console.WriteLine("query started"); Console.Write("cancel? "); int input = Console.Read(); if (input == 'Y' || input == 'y') { // cancel! cts.Cancel(); } } static void IntroParallel() { const int arraySize = 100000000; var data = new int[arraySize]; var r = new Random(); for (int i = 0; i < arraySize; i++) { data[i] = r.Next(40); } Stopwatch watch = new Stopwatch(); watch.Start(); var q1 = (from x in Partitioner.Create(data).AsParallel() where x < 80 select x).Sum(); watch.Stop(); Console.WriteLine(watch.ElapsedMilliseconds); } }
四、表达式树
表达式树是一个可以改变语义分析的编译器级别的功能,也就是可以为编写的不同的表达式语句,定义不同的执行函数。
通过树形结构来调用不同的处理函数。
例如:lambda表达式可以用于委托中,也可以用于Expression类型中作为参数,Expression有很多表达式的类型派生类,可以分析执行表达式,例如:
class Program { 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); } }
上述是lambda表达式用于Expression类型。
LINQ TO SQL中lambda表达式用于Expression<T>类型。
也可以定义自己的Expression<T>拓展方法类型和LINQ表达式,实现自己的表达式树,这样表达式树存在于程序集中,执行的时候会读取。
五、LINQ提供程序
LINQ语句.net框架中定义的目标对象有:LINQ to Objects, LINQ to XML,LINQ to SQL。
其中LINQ语句具体的解释由作用的数据源容器类型来决定。
例如LINQ to Objects中的Whered拓展方法定义为:
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource>s source, Func<TSource, bool> predicate);LINQ to SQL中的where拓展方法定义为:
public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource,bool>> predicate);
当在SQL中的where语句时候,因为作用的容器数据源类型是ADO中定义的ObjectContext类的CreateQuery<T>()方法返回一个实现了IQueryable<TSource>接口的ObjectQuery<T>对象,因此时候使用Queryable类的Where()方法。
LINQ 是比较深奥的主题,主要是用到了表达式树的函数式语言的编程思想,拓展方法拓展当前的数据源自定义拓展方法,数据源上进行数据的操作会创建各种类型的容器和需要的委托方法(lambda表达式),以及对各种数据源底层细节的封装对上层提供了统一的LINQ简易数据操作。
0 0
- LINQ统一数据操作语句
- LINQ to Entities统一数据存取方法解析(非原创)
- 使用Linq操作XML数据
- linq操作sqlserver数据库基本语句
- linq语句
- LINQ语句
- 演练:操作数据 (C#) (LINQ to SQL)
- c# Linq操作XML,查找节点数据
- Linq操作XML,查找节点数据
- 常用数据操作语句
- 数据操作语句-1
- 数据操作语句-2
- mysql数据操作语句
- LINQ to SQL 语句之Insert/Update/Delete 操作
- LINQ to SQL语句之Insert/Update/Delete操作
- LINQ to SQL语句(1)之Where操作
- LINQ to OBJECT语句之Join操作符的使用
- LINQ to SQL语句之Insert/Update/Delete操作
- 使用boost::filesystem实现目录遍…
- 多线程程序中死锁的分析和解决方案
- 多线程vs多进程(分析、比较和建议…
- poj3723Conscription
- 条件变量notify_all()和notify()的…
- LINQ统一数据操作语句
- 算法题:求所有和为N的子集
- npm发布注意事项
- 简化C++内存管理,避免内存泄露的…
- 使用并查集解决POJ1182
- 软件开发与写作
- c++中异常的时间代价
- QT4.6中将QImage保存为JPG格式
- QT中用Qpainter的drawText方法程序…