.NET LINQ数据转换
- 使用 LINQ 进行数据转换
语言集成查询 (LINQ) 不仅可用于检索数据, 而且还是一个功能强大的数据转换工具。 通过使用 LINQ 查询,您可以将源序列用作输入,并采用多种方式修改它以创建新输出序列。 您可以通过排序和分组来修改序列本身,而不必修改元素本身。但是,LINQ 查询的最强大功能可能在于它能够创建新类型。 这一功能在 select 子句中实现。 例如,可以执行下列任务:
-
- 将多个输入序列合并到具有新类型的单个输出序列中。
- 创建其元素只包含源序列中的各个元素的一个或几个属性的输出序列。
- 创建其元素包含对源数据执行的操作结果的输出序列。
- 创建不同格式的输出序列。
- 将多个输入联接到一个输出序列
可以使用 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=111,
Street="123 Main Street",
City="Seattle",
Scores= new List<int> {97, 92, 81, 60}},
new Student {First="Claire",
Last="O’Donnell",
ID=112,
Street="124 Main Street",
City="Redmond",
Scores= new List<int> {75, 84, 91, 39}},
new Student {First="Sven",
Last="Mortensen",
ID=113,
Street="125 Main Street",
City="Lake City",
Scores= new List<int> {88, 94, 65, 91}},
};
List<Teacher> teachers = new List<Teacher>()
{
new Teacher {First="Ann", Last="Beebe", ID=945, City = "Seattle"},
new Teacher {First="Alex", Last="Robinson", ID=956, City = "Redmond"},
new Teacher {First="Michiyo", Last="Sato", ID=972, 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();
}
}
|
- 选择各个源元素的子集
若要只选择源元素的一个成员,请使用点运算。在下面的示例中,假定 Customer 对象包含几个公共属性,其中包括名为 City 的字符串。在执行此查询时,此查询将生成字符串输出序列。
var query = from cust in Customers select cust.City;
|
若要创建包含源元素的多个属性的元素,可以使用具有命名对象或匿名类型的对象初始值设定项。
var query = from cust in Customer select new {Name = cust.Name, City = cust.City};
|
- 将内存中的对象转换为 XML
通过 LINQ 查询,可以轻松地在内存中的数据结构、SQL 数据库、ADO.NET 数据集和 XML 流或文档之间转换数据。
class XMLTransform
{
static void Main()
{
List<Student> students = new List<Student>()
{
new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores = new List<int>{97, 92, 81, 60}},
new Student {First="Claire", Last="O’Donnell", ID=112, Scores = new List<int>{75, 84, 91, 39}},
new Student {First="Sven", Last="Mortensen", ID=113, Scores = new List<int>{88, 94, 65, 91}},
};
var studentsToXML = new XElement("Root",
from student in students
let x = String.Format("{0},{1},{2},{3}", student.Scores[0],
student.Scores[1], student.Scores[2], student.Scores[3])
select new XElement("student",
new XElement("First", student.First),
new XElement("Last", student.Last),
new XElement("Scores", x)
)
);
Console.WriteLine(studentsToXML);
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
|
- 对源元素执行操作
输出序列可能不包含源序列的任何元素或元素属性。输出可能是通过将源元素用作输入参数计算出的值的序列。在执行下面这个简单查询时,此查询会输出一个字符串序列,该序列值表示根据 double 类型的元素的源序列进行的计算。
class FormatQuery
{
static void Main()
{
double[] radii = { 1, 2, 3 };
IEnumerable<string> query =
from rad in radii
select String.Format("Area = {0}", (rad * rad) * 3.14);
foreach (string s in query)
Console.WriteLine(s);
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
|