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

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

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

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

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

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

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

以下示例演示了查询:

 class DataTransformations
{
static void Main()
{
// 创建第一个数据源
List<Student> students = new List<Student>()
{
new Student { First="Svetlana",
Last="Omelchenko",
ID=,
Street="123 Main Street",
City="Seattle",
Scores= new List<int> { , , , } },
new Student { First="Claire",
Last="O’Donnell",
ID=,
Street="124 Main Street",
City="Redmond",
Scores= new List<int> { , , , } },
new Student { First="Sven",
Last="Mortensen",
ID=,
Street="125 Main Street",
City="Lake City",
Scores= new List<int> { , , , } },
}; // 创建第二个数据源
List<Teacher> teachers = new List<Teacher>()
{
new Teacher { First="Ann", Last="Beebe", ID=, City="Seattle" },
new Teacher { First="Alex", Last="Robinson", ID=, City="Redmond" },
new Teacher { First="Michiyo", Last="Sato", ID=, City="Tacoma" }
}; // 创建查询
var peopleInSeattle = (from student in students
where student.City == "Seattle"
select student.Last)
.Concat(from teacher in teachers
where teacher.City == "Seattle"
select teacher.Last); Console.WriteLine("The following students and teachers live in Seattle:");
// 执行查询
foreach (var person in peopleInSeattle)
{
Console.WriteLine(person);
} Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* 输出:
The following students and teachers live in Seattle:
Omelchenko
Beebe
*/

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

选择每个源元素的子集

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

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

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

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

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

将内存中对象转换为 XML
LINQ 查询可以轻松地在内存中数据结构、SQL 数据库、ADO.NET 数据集和 XML 流或文档之间转换数据。 以下示例将内存中数据结构中的对象转换为 XML 元素。
 class XMLTransform
{
static void Main()
{
// 使用集合初始值设定项创建数据源
// 学生类是在上述定义的
List<Student> students = new List<Student>()
{
new Student {First="Svetlana", Last="Omelchenko", ID=, Scores = new List<int>{, , , }},
new Student {First="Claire", Last="O’Donnell", ID=, Scores = new List<int>{, , , }},
new Student {First="Sven", Last="Mortensen", ID=, Scores = new List<int>{, , , }},
}; // 创建查询
var studentsToXML = new XElement("Root",
from student in students
let scores = string.Join(",", student.Scores)
select new XElement("student",
new XElement("First", student.First),
new XElement("Last", student.Last),
new XElement("Scores", scores)
) // end "student"
); // end "Root" // 执行查询
Console.WriteLine(studentsToXML); // Keep the console open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}

此代码生成以下 XML 输出:

<Root>
<student>
<First>Svetlana</First>
<Last>Omelchenko</Last>
<Scores>97,92,81,60</Scores>
</student>
<student>
<First>Claire</First>
<Last>O'Donnell</Last>
<Scores>75,84,91,39</Scores>
</student>
<student>
<First>Sven</First>
<Last>Mortensen</Last>
<Scores>88,94,65,91</Scores>
</student>
</Root>

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

对源元素执行操作

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

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

class FormatQuery
{
static void Main()
{
// 数据源
double[] radii = { , , }; // 查询表达式
IEnumerable<string> query =
from rad in radii
select $"Area = {rad * rad * Math.PI:F2}"; // 执行查询
foreach (string s in query)
Console.WriteLine(s); Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* 输出:
Area = 3.14
Area = 12.57
Area = 28.27
*/

其他技术请参考

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. Node EE方案 -- Rockerjs在微店的建设与发展

    本文是根据2019.4.13日参加 "Node-Party"论坛使用的PPT,加上笔者新的思考与沉淀而来.在此再次感谢贝贝网前端部门和芋头君以及相关与会人员的支持! -- 微店杨力 ...

  2. Delphi中动态调用TXMLDocument的经历

    var  vXMLDocument: TXMLDocument;begin  vXMLDocument := TXMLDocument.Create('c:/temp/temp.xml');  Cap ...

  3. 项目集成dubbo

    dubbo 用户指南: http://dubbo.io/User+Guide-zh.htm 开发指南:http://dubbo.io/Developer+Guide-zh.htm#DeveloperG ...

  4. CAP碎碎念

    整个2017年都在搞大数据平台,完全远离了机器学习,甚至都不记得写过类似ETL的job. 从数据到平台,从业务处理到基础服务. Metrics的收集,报警,生成报表.Data pipeline的准确性 ...

  5. Microsoft Development Platform Technologies

  6. 关于这次KPL春季决赛的感悟

    QG 4:0 横扫AG超玩会,关于这一点想写一些自己的感悟,AG超玩会一直都是 4:0 横扫别人,这次在冠军赛被别人横扫,一点喘息的机会都没有.   1.QGhappy 跟本没把AG超玩会放在眼里,很 ...

  7. 利用Rsync同步工具上传、删除目标文件

    Rsync是文件备份工具,当然也可以当做传输工具,管理远程服务器的文件 上传 rsync -avzP --progress --port 9106 /path/.../指定文件 root@192.16 ...

  8. 自动获取淘宝API数据访问的SessionKey

    最近在忙与淘宝做对接的工作,总体感觉淘宝的api文档做的还不错,不仅有沙箱测试环境,而且对于每一个api都可以通过api测试工具生成想要的代码,你完全可以先在测试工具中测试之后再进行代码的编写,这样就 ...

  9. C#基础原理拾遗——引用类型的值传递和引用传递

    以前写博客不深动,只搭个架子,像做笔记,没有自己的思考,也没什么人来看.这个毛病得改,就从这一篇开始- 最近准备面试,深感基础之重要,奈何我不是计算机科班出身,基础方面有些捉襟见肘.短期怎么补?做面实 ...

  10. c++类运算符重载遇到的函数形参问题

    class A { public: A(int arg1, int arg2); ~A(); A &operator = ( A &other); A operator + ( A & ...