记录LINQ标准查询运算符的学习

LINQ的延迟执行方式分两种,一种是流式处理,另一种是非流式处理。流式处理是指:当获取到的源元素足够计算时,就生成结果元素,不一定要获取全部源元素。

ToAsEnumerable

namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
Clump<string> fruitClump =
new Clump<string> { "apple", "passionfruit", "banana",
"mango", "orange", "blueberry", "grape", "strawberry" }; // 调用 Clump's Where() method with a predicate.
IEnumerable<string> query1 =
fruitClump.Where(fruit => fruit.Contains("o")); Console.WriteLine("query1 has been created.\n"); // 强迫使用 System.Linq.Enumerable 的 Where() 方法.
IEnumerable<string> query2 =
fruitClump.AsEnumerable().Where(fruit => fruit.Contains("o")); // Display the output.
Console.WriteLine("query2 has been created.");
}
}
class Clump<T> : List<T>
{
// Custom implementation of Where().
public IEnumerable<T> Where(Func<T, bool> predicate)
{
Console.WriteLine("In Clump's implementation of Where().");
return Enumerable.Where(this, predicate);
}
}
}

Cast

//ArrayList 继承的是IEnumerable 而非IEnumerable<T>
System.Collections.ArrayList fruits = new System.Collections.ArrayList();
fruits.Add("mango");
fruits.Add("apple");
fruits.Add("lemon"); //OrderBy扩展的是IEnumerable<T>。因此通过Cast<T>转为IEnumerable<T>
IEnumerable<string> query =
fruits.Cast<string>().OrderBy(fruit => fruit).Select(fruit => fruit); foreach (string fruit in query)
{
Console.WriteLine(fruit);
}

Concat 连接序列

Pet[] cats = GetCats();
Pet[] dogs = GetDogs(); IEnumerable<string> query =
cats.Select(cat => cat.Name).Concat(dogs.Select(dog => dog.Name)); foreach (string name in query)
{
Console.WriteLine(name);
} //用另一个select重载试试
IEnumerable<string> query1 =
    cats.Select((pet, index) => { if (index == 2) { return pet.Name; } else { return ""; } })
    .Concat(dogs.Select(dog=>dog.Name))

DefaultIfEmpty 如果序列为空,则返回一个具有默认值的单例类集合

Pet defaultPet = new Pet { Name = "Default Pet", Age =  };

List<Pet> pets1 =
new List<Pet>{ new Pet { Name="Barley", Age= },
new Pet { Name="Boots", Age= },
new Pet { Name="Whiskers", Age= } }; foreach (Pet pet in pets1.DefaultIfEmpty(defaultPet))
{
Console.WriteLine("Name: {0}", pet.Name);
} List<Pet> pets2 = new List<Pet>(); foreach (Pet pet in pets2.DefaultIfEmpty(defaultPet))
{
Console.WriteLine("\nName: {0}", pet.Name);
}

Distinct 返回元素不重复的元素,可以使用默认比较器,也可以传个新的

Product product1 = new Product { Name = "apple", Code =  };
Product[] products = { product1,
new Product { Name = "orange", Code = },
product1,
new Product { Name = "lemon", Code = } }; //在此处,使用默认比较器
IEnumerable<Product> noduplicates = products.Distinct(); //该不该生产当前结果元素,只需要判断之前的源元素有没有一样的,知道判断到有,就不生成
foreach (var product in noduplicates)
Console.WriteLine(product.Name + " " + product.Code);

Except 返回序列之间的差值

double[] numbers1 = { 2.0, 2.0, 2.1, 2.2, 2.3, 2.3, 2.4, 2.5 };
double[] numbers2 = { 2.2 }; IEnumerable<double> onlyInFirstSet = numbers1.Except(numbers2); foreach (double number in onlyInFirstSet)
Console.WriteLine(number);

GroupJoin 两个序列进行分组联接

Person magnus = new Person { Name = "Hedlund, Magnus" };
Person terry = new Person { Name = "Adams, Terry" }; Pet barley = new Pet { Name = "Barley", Owner = terry };
Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus }; List<Person> people = new List<Person> { magnus, terry };
List<Pet> pets = new List<Pet> { barley, boots, daisy }; //Pet的Owner和Person关联
var query =
people.GroupJoin(pets,
person => person,
pet => pet.Owner,
(person, petCollection) =>
new
{
OwnerName = person.Name,
Pets = petCollection.Select(pet => pet.Name)
}); foreach (var obj in query)
{
Console.WriteLine("{0}:", obj.OwnerName);
foreach (string pet in obj.Pets)
{
Console.WriteLine(" {0}", pet);
}
}

Intersect 求序列交集

Product product = new Product { Name = "apple", Code =  };

Product[] store1 = { product,
new Product { Name = "orange", Code = } }; Product[] store2 = { product,
new Product { Name = "lemon", Code = } }; //在这里 使用默认比较器求差值
var products = store1.Intersect(store2); foreach(var item in products)
{
Console.WriteLine(item.Name);
}

Join基于匹配建对序列的元素进行关联

Person magnus = new Person { Name = "Hedlund, Magnus" };
Person terry = new Person { Name = "Adams, Terry" };
Person charlotte = new Person { Name = "Weiss, Charlotte" }; Pet barley = new Pet { Name = "Barley", Owner = terry };
Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus }; List<Person> people = new List<Person> { magnus, terry, charlotte };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, daisy }; //pet的owner和person关联
var query =
people.Join(pets,
person => person,
pet => pet.Owner,
(person, pet) =>
new { OwnerName = person.Name, Pet = pet.Name }); foreach (var obj in query)
{
Console.WriteLine(
"{0} - {1}",
obj.OwnerName,
obj.Pet);
}

OfType 根据指定类型筛选序列指定的元素

System.Collections.ArrayList fruits = new System.Collections.ArrayList();
fruits.Add("Mango");
fruits.Add("Orange");
fruits.Add("Apple");
fruits.Add(3.0);
fruits.Add("Banana"); // Apply OfType() to the ArrayList.
IEnumerable<string> query1 = fruits.OfType<string>(); Console.WriteLine("Elements of type 'string' are:");
foreach (string fruit in query1)
{
Console.WriteLine(fruit);
} Console.WriteLine("Elements of type 'int' are:");
IEnumerable<double> query2 = fruits.OfType<double>();
foreach (var num in query2)
{
Console.WriteLine(num);
}

Range 生成指定范围内的序列

IEnumerable<int> squares = Enumerable.Range(, ).Select(x => x * x);

foreach (int num in squares)
{
Console.WriteLine(num);
}

Repeat生成一个包含重复值的序列

IEnumerable<string> strings =
Enumerable.Repeat("I like programming.", ); foreach (String str in strings)
{
Console.WriteLine(str);
}

Select 将序列中的每个元素投影到新表单

string[] fruits = { "apple", "banana", "mango", "orange",
"passionfruit", "grape" }; var query =
fruits.Select((fruit, index) => new { index,str=fruit.Substring(,index)}); foreach (var obj in query)
{
Console.WriteLine("{0}", obj);
}

SelectMany 将序列的每个元素投影到 IEnumerable<T> ,然后,每个元素投影到的结果序列合并成一个大的序列。

PetOwner[] petOwners =
{
new PetOwner { Name="Higa",
Pets = new List<string>{ "Scruffy", "Sam" } },
new PetOwner { Name="Ashkenazi",
Pets = new List<string>{ "Walker", "Sugar" } },
new PetOwner { Name="Price",
Pets = new List<string>{ "Scratches", "Diesel" } },
new PetOwner { Name="Hines",
Pets = new List<string>{ "Dusty" } }
}; //想要的结果,Higa养猪人都有哪些猪,排成一行行的结果。
// {Owner=Higa, Pet=Scruffy}
// {Owner=Higa, Pet=Sam} var query = petOwners.Where(owner=>owner.Name=="Higa")
.SelectMany(owner => owner.Pets, (owner, pet) => new { owner = owner.Name, pet });
foreach(var obj in query)
{
Console.WriteLine(obj);
}
Skip 跳过指定数量的元素,返回一个剩下元素组成的新序列
int[] grades = { , , , , , ,  };

IEnumerable<int> lowerGrades =
grades.Skip(); foreach (int grade in lowerGrades)
{
Console.WriteLine(grade);
} //返回结果
//70
//56
//92
//98
//
SkipWhile 当条件为true,前面的元素忽略,剩下的元素组成一个新序列。
下面有坑,请注意。
int[] grades = { , , , , , ,  };

IEnumerable<int> newGrades =
grades.SkipWhile(grade => grade >= ); foreach (int grade in newGrades)
{
Console.WriteLine(grade);
} Console.WriteLine("\n"); //排序之后的跳过
IEnumerable<int> lowerGrades =
grades.OrderByDescending(g=>g).SkipWhile(grade => grade >= ); foreach (int grade in lowerGrades)
{
Console.WriteLine(grade);
} 控制台输出结果:
59
82
70
56
92
98
85 70
59
5
Take从序列的开头返回指定数量的相邻元素
int[] grades = { , , , , , ,  };

IEnumerable<int> newGrades =
grades.Take(); foreach (int grade in newGrades)
{
Console.WriteLine(grade);
}
TakeWhile 只要指定的条件为 true,就会返回序列的元素,从开头开始取,直到不满足条件,剩下的元素也不返回了。
string[] fruits = { "apple", "banana", "mango", "orange",
"passionfruit", "grape" }; IEnumerable<string> query =
fruits.TakeWhile(fruit => String.Compare("orange", fruit, true)!= ); foreach (string fruit in query)
{
Console.WriteLine(fruit);
} Console.WriteLine("\n"); IEnumerable<string> query1 =
fruits.TakeWhile(fruit => String.Compare("apple", fruit, true) == ); foreach (string fruit in query1)
{
Console.WriteLine(fruit);
} /*
输出结果: apple
banana
mango apple
*/

Union 生成两个序列的并集

跑了好些示例,发现只要通过标准运算符生成的元素如果要通过判断相等操作,都有比较器可以传入的函数。

int[] ints1 = { , , , , , , ,  };
int[] ints2 = { , , , , , , , }; IEnumerable<int> union = ints1.Union(ints2); foreach (int num in union)
{
Console.Write("{0} ", num);
}

Where 基于条件筛选序列,太常用了。

List<string> fruits =
new List<string> { "apple", "passionfruit", "banana", "mango",
"orange", "blueberry", "grape", "strawberry" }; IEnumerable<string> query = fruits.Where(fruit => fruit.Length < ); foreach (string fruit in query)
{
Console.WriteLine(fruit);
}
/*
This code produces the following output: apple
mango
grape
*/
 

LINQ标准查询运算符的执行方式-延时之流式处理的更多相关文章

  1. LINQ标准查询运算符的执行方式-即时

    即时,声明查询的位置立即执行.查询返回如果是不可以枚举的的结果,都会立即执行. 执行方式为“”即时”的查询运算符有下面这些. Aggregate 应用累计器函数和结果选择器,返回传入泛型类型TSour ...

  2. C#3.0新增功能09 LINQ 标准查询运算符 03 按执行方式的分类

    连载目录    [已更新最新开发文章,点击查看详细] 标准查询运算符方法的 LINQ to Objects 实现主要通过两种方法之一执行:立即执行和延迟执行.使用延迟执行的查询运算符可以进一步分为两种 ...

  3. .NET LINQ标准查询运算符

    标准查询运算符概述      “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法. 大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了 IEnumerable<T> ...

  4. C#3.0新增功能09 LINQ 标准查询运算符 04 运算

    连载目录    [已更新最新开发文章,点击查看详细] 本篇主要介绍标准查询运算符的常用运算功能. 01 对数据排序 排序操作基于一个或多个属性对序列的元素进行排序. 第一个排序条件对元素执行主要排序. ...

  5. C#3.0新增功能09 LINQ 标准查询运算符 01 概述

    连载目录    [已更新最新开发文章,点击查看详细] 标准查询运算符 是组成 LINQ 模式的方法. 这些方法中的大多数都作用于序列:其中序列指其类型实现 IEnumerable<T> 接 ...

  6. C#3.0新增功能09 LINQ 标准查询运算符 02 查询表达式语法

    连载目录    [已更新最新开发文章,点击查看详细] 某些使用更频繁的标准查询运算符具有专用的 C# 语言关键字语法,使用这些语法可以在查询表达式中调用这些运算符. 查询表达式是比基于方法的等效项更具 ...

  7. linq标准查询运算符

    Order By操作 适用场景:对查询出的语句进行排序,比如按时间排序等等. 说明:按指定表达式对集合排序:延迟,:按指定表达式对集合排序:延迟,默认是升序,加上descending表示降序,对应的扩 ...

  8. .NET中那些所谓的新语法之四:标准查询运算符与LINQ

    开篇:在上一篇中,我们了解了预定义委托与Lambda表达式等所谓的新语法,这一篇我们继续征程,看看标准查询运算符和LINQ.标准查询运算符是定义在System.Linq.Enumerable类中的50 ...

  9. “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法

    “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> 接口或 IQueryable& ...

随机推荐

  1. Flask登录认证

    login函数 @app.route('/login/', methods=['GET', 'POST']) def login(): if request.method == 'GET': retu ...

  2. Qt Installer Framework翻译(1)

    IFW概览 Qt Installer Framework 提供了一组工具和程序来创建安装程序,并在不重写源代码的情况下将它们部署到所有受支持的桌面 Qt 平台上.安装程序具有本地化外观,并且可以感知运 ...

  3. 最强PostMan使用教程

    最近需要测试产品中的REST API,无意中发现了PostMan这个chrome插件,把玩了一下,发现postman秉承了一贯以来google工具强大,易用的特质.独乐乐不如众乐乐,特此共享出来给大伙 ...

  4. .Net Core建站(2):EF Core+CodeFirst数据库迁移

    上一篇的话,说了下怎么使用EF7 实现 CodeFirst去生成数据库, 其实还有好多问题的,这次一点一点的解决吧,都挺简单,不过零零散散的,, 1.读取配置文件,获得链接字符串 2.使用数据库进行增 ...

  5. Java框架-MyBatis三剑客之MyBatis Generator(mybatis-generator MBG插件)详解

    生成器设计思路: 连接数据库 -> 获取表结构 -> 生成文件 1 下载与安装 官网文档入口 最方便的 maven 插件使用方式 贴至pom 文件 2 新建配置文件 填充配置信息(官网示例 ...

  6. PMP——项目管理的价值观与方法论

    关于项目管理的十个成语: 未雨绸缪(计划.风险):识别风险.做出计划.并指定负责人: 防微杜渐(监控.纠正):持续的实时的监控计划,监控和发现偏差,并进行纠正: 资源集成(整合.采购):把最专业的资源 ...

  7. Docker Mysql部署与使用

    参考链接:Docker 安装 Mysql 详解

  8. 原生Ajax发送get、post请求每一步

    说明 发送Ajax的请求的核心对象是XMLHttpRequest,因此我们需要了解该对象的相关属性和方法 方法(图一) 属性(图二) 第一步:创建 XMLHttpRequest对象,下面都简写为 xh ...

  9. git看这一篇就够用了

    前言 本文是参考廖雪峰老师的Git资料再加上我自己对Git的理解,记录我的Git学习历程. Git是什么 官方话:Git是一个免费的开源分布式版本控制系统,旨在快速高效地处理从小型到大型项目的所有事务 ...

  10. 《快乐编程大本营》java语言训练班-第4课:java流程控制

    <快乐编程大本营>java语言训练班-第4课:java流程控制 第1节. 顺序执行语句 第2节. 条件分支语句:if条件语句 第3节. 条件分支语句:switch 条件语句 第4节. 条件 ...