C#2008与.NET 3.5 高级程序设计读书笔记(24)-- LINQ API编程
1.LINQ to Objects
术语“LINQ to Objects”是指直接对任意 IEnumerable 或 IEnumerable<T> 集合使用 LINQ 查询,无需使用中间 LINQ 提供程序或 API,如 LINQ to SQL 或 LINQ to XML。可以使用 LINQ 来查询任何可枚举的集合,如 List<T>、Array 或 Dictionary<TKey, TValue>。该集合可以是用户定义的集合,也可以是 .NET Framework API 返回的集合。
using System;
using System.Collections;
using System.Linq;
namespace NonGenericLINQ
{
public class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int[] Scores { get; set; }
}
class Program
{
static void Main(string[] args)
{
ArrayList arrList = new ArrayList();
arrList.Add(
new Student
{
FirstName = "Svetlana", LastName = "Omelchenko", Scores = new int[] { 98, 92, 81, 60 }
});
arrList.Add(
new Student
{
FirstName = "Claire", LastName = "O’Donnell", Scores = new int[] { 75, 84, 91, 39 }
});
arrList.Add(
new Student
{
FirstName = "Sven", LastName = "Mortensen", Scores = new int[] { 88, 94, 65, 91 }
});
arrList.Add(
new Student
{
FirstName = "Cesar", LastName = "Garcia", Scores = new int[] { 97, 89, 85, 82 }
});
var query = from Student student in arrList
where student.Scores[0] > 95
select student;
foreach (Student s in query)
Console.WriteLine(s.LastName + ": " + s.Scores[0]);
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
2.LINQ to DataSet
语言集成查询 (LINQ) 查询适用于实现 IEnumerable<T> 接口或 IQueryable 接口的数据源。DataTable 类不实现任何一个接口,所以如果要使用 DataTable 作为LINQ 查询的 From 子句中的源,则必须调用 AsEnumerable 方法。
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable orders = ds.Tables["SalesOrderHeader"];
var query =
from order in orders.AsEnumerable()
where order.Field<bool>("OnlineOrderFlag") == true
select new
{
SalesOrderID = order.Field<int>("SalesOrderID"),
OrderDate = order.Field<DateTime>("OrderDate"),
SalesOrderNumber = order.Field<string>("SalesOrderNumber")
};
foreach (var onlineOrder in query)
{
Console.WriteLine("Order ID: {0} Order date: {1:d} Order number: {2}",
onlineOrder.SalesOrderID,
onlineOrder.OrderDate,
onlineOrder.SalesOrderNumber);
}
如果在应用程序设计时已知 DataSet 的架构,则建议在使用 LINQ to DataSet 时使用类型化 DataSet。类型化 DataSet 是从 DataSet 中派生的类。因此,它继承 DataSet 的所有方法、事件和属性。此外,类型化 DataSet 还提供强类型方法、事件和属性。这意味着可以按名称而不使用基于集合的方法来访问表和列。这可使查询更简单、更具可读性。
var query = from o in orders
where o.OnlineOrderFlag == true
select new { o.SalesOrderID,
o.OrderDate,
o.SalesOrderNumber };
foreach(var order in query)
{
Console.WriteLine("{0}\t{1:d}\t{2}",
order.SalesOrderID,
order.OrderDate,
order.SalesOrderNumber);
}
3.LINQ to XML
LINQ to XML 可以看作是一个 “better DOM” 编程模型,可以和 System.Xml.dll 程序集中的很多成员交互。
一、命名空间
System.Xml.Linq.dll 程序集定义了三个命名空间:System.Xml.Linq, System.Xml.Schema 和 System.Xml.XPath
最核心的是 System.Xml.Linq, 定义了对应 XML 文档个方面的很多类型
Member of System.Xml.Linq |
Meaning in Life |
XAttribute |
Represents an XML attribute on a given XML element |
XComment |
Represents an XML comment |
XDeclaration |
Represents the opening declaration of an XML document |
XDocument |
Represents the entirety of an XML document |
XElement |
Represents a given element within an XML document |
XName/XNamespace |
Provide a very simple manner to define and reference XML namespaces |
二、编程方式创建XML文档
以前的 .NET XML编程模型需要使用很多冗长的
DOM API,而 LINQ to XML 则完全可以用与 DOM 无关的方式与 XML 文档交互。这样不但大大减少了代码行,而且这种编程模型可以直接映射到格式良好的XML文档结构。
{
// A "functional" approach to build an
// XML element in memory.
XElement inventory =
new XElement("Inventory",
new XElement("Car", new XAttribute("ID", "1"),
new XElement("Color", "Green"),
new XElement("Make", "BMW"),
new XElement("PetName", "Stan")
)
);
// Call ToString() on our XElement.
Console.WriteLine(inventory);
}
在内存中创建XML文档
{
XDocument inventoryDoc =
new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XComment("Current Inventory of AutoLot"),
new XElement("Inventory",
new XElement("Car", new XAttribute("ID", "1"),
new XElement("Color", "Green"),
new XElement("Make", "BMW"),
new XElement("PetName", "Stan")
),
new XElement("Car", new XAttribute("ID", "2"),
new XElement("Color", "Pink"),
new XElement("Make", "Yugo"),
new XElement("PetName", "Melvin")
)
)
);
// Display the document and save to disk.
Console.WriteLine(inventoryDoc);
inventoryDoc.Save("SimpleInventory.xml");
}
三、使用 LINQ 查询创建XML文档
{
// Create an anonymous array of anonymous types.
var data = new [] {
new { PetName = "Melvin", ID = 10 },
new { PetName = "Pat", ID = 11 },
new { PetName = "Danny", ID = 12 },
new { PetName = "Clunker", ID = 13 }
};
// Now enumerate over the array to build
// an XElement.
XElement vehicles =
new XElement("Inventory",
from c in data
select new XElement("Car",
new XAttribute("ID", c.ID),
new XElement("PetName", c.PetName)
)
);
Console.WriteLine(vehicles);
}
四、加载和解析XML内容
{
// Build an XElement from string.
string myElement =
@"<Car ID ='3'>
<Color>Yellow</Color>
<Make>Yugo</Make>
</Car>";
XElement newElement = XElement.Parse(myElement);
Console.WriteLine(newElement);
Console.WriteLine();
// Load the SimpleInventory.xml file.
XDocument myDoc = XDocument.Load("SimpleInventory.xml");
Console.WriteLine(myDoc);
}
五、遍历内存中的XML文档
XML示例:
<?xml version="1.0" encoding="utf-8"?>
<Inventory>
<Car carID ="0">
<Make>Ford</Make>
<Color>Blue</Color>
<PetName>Chuck</PetName>
</Car>
<Car carID ="1">
<Make>VW</Make>
<Color>Silver</Color>
<PetName>Mary</PetName>
</Car>
<Car carID ="2">
<Make>Yugo</Make>
<Color>Pink</Color>
<PetName>Gipper</PetName>
</Car>
<Car carID ="55">
<Make>Ford</Make>
<Color>Yellow</Color>
862 CHAPTER 24 n PROGRAMMING WITH THE LINQ APIS
<PetName>Max</PetName>
</Car>
<Car carID ="98">
<Make>BMW</Make>
<Color>Black</Color>
<PetName>Zippy</PetName>
</Car>
</Inventory>
加载
{
Console.WriteLine("***** Fun with LINQ to XML *****\n");
// Load the Inventory.xml document into memory.
XElement doc = XElement.Load("Inventory.xml");
// We will author each of these next
PrintAllPetNames(doc);
Console.WriteLine();
GetAllFords(doc);
Console.ReadLine();
}
遍历
{
var petNames = from pn in doc.Descendants("PetName")
select pn.Value;
foreach (var name in petNames)
Console.WriteLine("Name: {0}", name);
}
查询
{
var fords = from c in doc.Descendants("Make")
where c.Value == "Ford"
select c;
foreach (var f in fords)
Console.WriteLine("Name: {0}", f);
}
六、修改 XML文档
{
// Add 5 new purple Fords to the incoming document.
for (int i = 0; i < 5; i++)
{
// Create a new XElement
XElement newCar =
new XElement("Car", new XAttribute("ID", i + 1000),
new XElement("Color", "Green"),
new XElement("Make", "Ford"),
new XElement("PetName", "")
);
// Add to doc.
doc.Add(newCar);
}
// Show the updates.
Console.WriteLine(doc);
}