语言集成查询 (LINQ) 不只是检索数据。 它也是用于转换数据的强大工具。 通过使用 LINQ查询,可以使用源序列作为输入,并通过多种方式对其进行修改,以创建新的输出序列。通过排序和分组,你可以修改序列本身,而无需修改这些元素本身。 但也许 LINQ 查询最强大的功能是创建新类型。 这可以在 select 子句中完成。 例如,可以执行下列任务:

  • 将多个输入序列合并为具有新类型的单个输出序列。

  • 创建其元素由源序列中每个元素的一个或多个属性组成的输出序列。

  • 创建其元素由对源数据执行的操作结果组成的输出序列。

  • 创建其他格式的输出序列。 例如,可以将数据从 SQL 行或文本文件转换为 XML。

这只是几个例子。 当然,可以以各种方式在同一查询中组合这些转换。 此外,一个查询的输出序列可以用作新查询的输入序列。

将多个输入联接到一个输出序列中
可以使用 LINQ 查询创建包含元素的输出序列,这些元素来自多个输入序列。 以下示例演示如何组合两个内存中数据结构,但相同的原则可应用于组合来自 XML 或 SQL 或数据集源的数据。 假设以下两种类类型:
  1. class Student
  2. {
  3. public string First { get; set; }
  4. public string Last {get; set;}
  5. public int ID { get; set; }
  6. public string Street { get; set; }
  7. public string City { get; set; }
  8. public List<int> Scores;
  9. }
  10.  
  11. class Teacher
  12. {
  13. public string First { get; set; }
  14. public string Last { get; set; }
  15. public int ID { get; set; }
  16. public string City { get; set; }
  17. }

以下示例演示了查询:

  1. class DataTransformations
  2. {
  3. static void Main()
  4. {
  5. // 创建第一个数据源
  6. List<Student> students = new List<Student>()
  7. {
  8. new Student { First="Svetlana",
  9. Last="Omelchenko",
  10. ID=,
  11. Street="123 Main Street",
  12. City="Seattle",
  13. Scores= new List<int> { , , , } },
  14. new Student { First="Claire",
  15. Last="O’Donnell",
  16. ID=,
  17. Street="124 Main Street",
  18. City="Redmond",
  19. Scores= new List<int> { , , , } },
  20. new Student { First="Sven",
  21. Last="Mortensen",
  22. ID=,
  23. Street="125 Main Street",
  24. City="Lake City",
  25. Scores= new List<int> { , , , } },
  26. };
  27.  
  28. // 创建第二个数据源
  29. List<Teacher> teachers = new List<Teacher>()
  30. {
  31. new Teacher { First="Ann", Last="Beebe", ID=, City="Seattle" },
  32. new Teacher { First="Alex", Last="Robinson", ID=, City="Redmond" },
  33. new Teacher { First="Michiyo", Last="Sato", ID=, City="Tacoma" }
  34. };
  35.  
  36. // 创建查询
  37. var peopleInSeattle = (from student in students
  38. where student.City == "Seattle"
  39. select student.Last)
  40. .Concat(from teacher in teachers
  41. where teacher.City == "Seattle"
  42. select teacher.Last);
  43.  
  44. Console.WriteLine("The following students and teachers live in Seattle:");
  45. // 执行查询
  46. foreach (var person in peopleInSeattle)
  47. {
  48. Console.WriteLine(person);
  49. }
  50.  
  51. Console.WriteLine("Press any key to exit.");
  52. Console.ReadKey();
  53. }
  54. }
  55. /* 输出:
  56. The following students and teachers live in Seattle:
  57. Omelchenko
  58. Beebe
  59. */

有关详细信息,请参阅 join 子句和 select 子句

选择每个源元素的子集

有两种主要方法来选择源序列中每个元素的子集:

  1. 若要仅选择源元素的一个成员,请使用点操作。 在以下示例中,假设 Customer 对象包含多个公共属性,包括名为 City 的字符串。 在执行时,此查询将生成字符串的输出序列。

    1. var query = from cust in Customers
    2. select cust.City;
  2. 若要创建包含多个源元素属性的元素,可以使用带有命名对象或匿名类型的对象初始值设定项。 以下示例演示如何使用匿名类型封装每个 Customer 元素的两个属性:

    1. var query = from cust in Customer
    2. select new {Name = cust.Name, City = cust.City};

有关详细信息,请参阅对象和集合初始值设定项匿名类型

将内存中对象转换为 XML
LINQ 查询可以轻松地在内存中数据结构、SQL 数据库、ADO.NET 数据集和 XML 流或文档之间转换数据。 以下示例将内存中数据结构中的对象转换为 XML 元素。
  1. class XMLTransform
  2. {
  3. static void Main()
  4. {
  5. // 使用集合初始值设定项创建数据源
  6. // 学生类是在上述定义的
  7. List<Student> students = new List<Student>()
  8. {
  9. new Student {First="Svetlana", Last="Omelchenko", ID=, Scores = new List<int>{, , , }},
  10. new Student {First="Claire", Last="O’Donnell", ID=, Scores = new List<int>{, , , }},
  11. new Student {First="Sven", Last="Mortensen", ID=, Scores = new List<int>{, , , }},
  12. };
  13.  
  14. // 创建查询
  15. var studentsToXML = new XElement("Root",
  16. from student in students
  17. let scores = string.Join(",", student.Scores)
  18. select new XElement("student",
  19. new XElement("First", student.First),
  20. new XElement("Last", student.Last),
  21. new XElement("Scores", scores)
  22. ) // end "student"
  23. ); // end "Root"
  24.  
  25. // 执行查询
  26. Console.WriteLine(studentsToXML);
  27.  
  28. // Keep the console open in debug mode.
  29. Console.WriteLine("Press any key to exit.");
  30. Console.ReadKey();
  31. }
  32. }

此代码生成以下 XML 输出:

  1. <Root>
  2. <student>
  3. <First>Svetlana</First>
  4. <Last>Omelchenko</Last>
  5. <Scores>97,92,81,60</Scores>
  6. </student>
  7. <student>
  8. <First>Claire</First>
  9. <Last>O'Donnell</Last>
  10. <Scores>75,84,91,39</Scores>
  11. </student>
  12. <student>
  13. <First>Sven</First>
  14. <Last>Mortensen</Last>
  15. <Scores>88,94,65,91</Scores>
  16. </student>
  17. </Root>

有关详细信息,请参阅在 C# 中创建 XML 树 (LINQ to XML)

对源元素执行操作

输出序列可能不包含源序列中的任何元素或元素属性。 输出可能是使用源元素作为输入参数而计算得出的值序列。 以下简单查询在执行时会输出一串字符串,其值表示基于 double类型的元素的源序列的计算结果。

如果查询将被转换为另一个域,则不支持在查询表达式中调用方法。 例如,不能在 LINQ to SQL 中调用普通的 C# 方法,因为 SQL Server 没有用于它的上下文。 但是,可以将存储过程映射到方法并调用这些方法。 有关详细信息,请参阅存储过程

  1. class FormatQuery
  2. {
  3. static void Main()
  4. {
  5. // 数据源
  6. double[] radii = { , , };
  7.  
  8. // 查询表达式
  9. IEnumerable<string> query =
  10. from rad in radii
  11. select $"Area = {rad * rad * Math.PI:F2}";
  12.  
  13. // 执行查询
  14. foreach (string s in query)
  15. Console.WriteLine(s);
  16.  
  17. Console.WriteLine("Press any key to exit.");
  18. Console.ReadKey();
  19. }
  20. }
  21. /* 输出:
  22. Area = 3.14
  23. Area = 12.57
  24. Area = 28.27
  25. */

其他技术请参考

C#3.0新增功能09 LINQ 基础05 使用 LINQ 进行数据转换的更多相关文章

  1. C#3.0新增功能09 LINQ 基础04 基本 LINQ 查询操作

    连载目录    [已更新最新开发文章,点击查看详细] 本篇介绍 LINQ 查询表达式和一些在查询中执行的典型操作. 获取数据源 在 LINQ 查询中,第一步是指定数据源. 和大多数编程语言相同,在使用 ...

  2. C#3.0新增功能09 LINQ 基础07 LINQ 中的查询语法和方法语法

    连载目录    [已更新最新开发文章,点击查看详细] 介绍性的语言集成查询 (LINQ) 文档中的大多数查询是使用 LINQ 声明性查询语法编写的.但是在编译代码时,查询语法必须转换为针对 .NET ...

  3. C#3.0新增功能09 LINQ 基础01 语言集成查询

    连载目录    [已更新最新开发文章,点击查看详细] 语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称. 数据查询历来都表示为简单的字符串,没有编译时类型检查或 Inte ...

  4. C#3.0新增功能09 LINQ 基础02 LINQ 查询简介

    连载目录    [已更新最新开发文章,点击查看详细] 查询 是一种从数据源检索数据的表达式. 查询通常用专门的查询语言来表示. 随着时间的推移,人们已经为各种数据源开发了不同的语言:例如,用于关系数据 ...

  5. C#3.0新增功能09 LINQ 基础03 LINQ 和泛型类型

    连载目录    [已更新最新开发文章,点击查看详细] LINQ 查询基于 .NET Framework 版本 2.0 中引入的泛型类型. 无需深入了解泛型即可开始编写查询. 但是,可能需要了解 2 个 ...

  6. C#3.0新增功能09 LINQ 基础08 支持 LINQ 的 C# 功能

    连载目录    [已更新最新开发文章,点击查看详细] 查询表达式 查询表达式使用类似于 SQL 或 XQuery 的声明性语法来查询 IEnumerable 集合. 在编译时,查询语法转换为对 LIN ...

  7. C#3.0新增功能09 LINQ 基础06 LINQ 查询操作中的类型关系

    连载目录    [已更新最新开发文章,点击查看详细] 若要有效编写查询,应了解完整的查询操作中的变量类型是如何全部彼此关联的. 如果了解这些关系,就能够更容易地理解文档中的 LINQ 示例和代码示例. ...

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

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

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

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

随机推荐

  1. VPS用来配置上网外,还可以做一个同步盘

    我曾经在一个活动的博文里说过,男人必须要有一个VPS和一个树莓派,VPS这个东西,以后会是中国男人的一种必备技能,今天又有一个小伙伴请教我VPS的用法,我就简单说说我目前使用的情况.首先我希望你能有点 ...

  2. UILabel实现自适应宽高需要注意的地方(二)

    需求图如下所示   UILabel "上期"   距离屏幕最左边 有35px UILabel "下期"   距离屏幕最右边 有35px 进行中文字在UIlabe ...

  3. 取得文件夹内容信息(使用IShellFolder接口)

    翻译自MSDN 2005 -> Win32 和 COM 开发 -> User Interface -> Windows User Experience -> Windows S ...

  4. Ural_1169_Pairs

    此题略坑... 思路:把N个点分成m若干个联通子图,然后用m-1个桥把这m个联通子图连接起来即可. 若每个联通子图内部都是完全图也符合题意,但答案却是Wrong Answer,只有把每个联通子图内部当 ...

  5. 打包成war包之后如何读取配置文件

    今天工作开发中遇到一个问题:在idea运行的项目读取配置文件没有问题,打包成war包之后就会报错java.io.FileNotFoundException: class path resource 原 ...

  6. Python开发【第四篇】: 三大器和内置函数

    内容概要 函数名 闭包 迭代器 生成器 推导式与表达式 内置函数 装饰器 初识递归 1.函数名 函数名的运用: 函数名是一个变量,但它是一个特殊的变量,与括号配合可以执行函数的变量. 01. 函数名的 ...

  7. C++ 洛谷 P2458 [SDOI2006]保安站岗 from_树形DP

    P2458 [SDOI2006]保安站岗 没学树形DP的,看一下. 题目大意:一棵树有N个节点,现在需要将所有节点都看守住,如果我们选择了节点i,那么节点i本身,节点i的父亲和儿子都会被看守住. 每个 ...

  8. seo外链发布之论坛外链

    目前最常见的seo外链方式有5种,之前大发迹创业项目网写文章分享过,详情可以查看文章<[网站SEO优化]最常见的五种软文外链发布方式!>,这篇文章不说其他的几种发外链,就来讲讲通过论坛建设 ...

  9. kafka入门(二)分区和group

    topic 在kafka中消息是按照topic进行分类的:每条发布到Kafka集群的消息都有一个类别,这个类别被称为topic parition 一个topic可以配置几个parition,每一个分区 ...

  10. Ural 2064:Caterpillars(思维暴力)

    http://acm.timus.ru/problem.aspx?space=1&num=2064 题意:有n只虫子在爬树,每个虫子往上爬ti距离后会往下掉落ti距离,每爬一个单位距离耗费一个 ...