Makeup Querying Collections
filtering a collection [LINQ] static void Main() |
LINQ is what C#3.5 is all about at its heart. In particular, it contains query expressions that allow a declarative style for creating queries on various data sources.
Actually, LINQ is that while query expressions are not particularly suitable for simple task,they're very, very good for more complicated situations that would be hard to read if written out in the equivalent method calls.
Now let's look at a code to join the sample products with the sample suppliers (obviously based on the supplier ID), apply the same price filter as before to the products, sort by supplier name and then product name, and print out the name of both supplier and product for each match.
*So , in earlier versions of C# it would have been a nightmare to implement. In LINQ, it's almost trivial!
Joing ,filtering , ordering, and projecting
static void Main()
{ //Get DataSource List<ProductWithSupplierID> products = ProductWithSupplierID.GetSampleProducts(); List<Supplier> suppliers = Supplier.GetSampleSuppliers(); //on p.SupplierID = s.SupplierID //Error:Expected contextual keyword 'equals' var filtered = from p in products join s in suppliers on p.SupplierID equals s.SupplierID where p.Price > 10 orderby s.Name, p.Name select new { SupplierName = s.Name, ProductName = p.Name }; foreach (var n in filtered) { Console.WriteLine("print out" + n.SupplierName, n.ProductName); } } It looks remarkably like SQL, This is the reaction of many people on first hearing. |
So, we maybe getting data from any number of sources:XML
<?xml version="1.0"?>
<Data> <Products> <Product Name="Company" Price="9.99" SupplierID="1" /> <Product Name="Assassins" Price="14.99" SupplierID="2" /> <Product Name="Frogs" Price="13.99" SupplierID="1" /> <Product Name="Sweeney Todd" Price="10.99" SupplierID="3" /> </Products> <Suppliers> <Supplier Name="Solely Sondheim" SupplierID="1" /> <Supplier Name="CD-by-CD-by-Sondheim" SupplierID="2" /> <Supplier Name="Barbershop CDs" SupplierID="3" /> </Suppliers> </Data> Well,the xml file is simple enough, but what's the best way of extracting the data from it? Query it? Join on it? OK, continue |
Shows how much work we have to do in LINQ to XML
static void Main()
{ XDocument xdoc = XDocument.Load("DataSoure.XML"); ///Descendants: Returns a filtered collection of the descendent elements for this document or element,in document order. Only elements that have a matching XName are included in the collection. ///按文档顺序返回此文档或元素的经过筛选的子代元素集合。集合中只包括具有匹配 XName 的元素 var filtered = from p in xdoc.Descendants("Product") join s in xdoc.Descendants("Supplier") on Convert.ToInt32(p.Attribute("SupplierID")) equals (Int32)s.Attribute("SupplierID") where Convert.ToDecimal(p.Attribute("Price")) > 10 orderby Convert.ToString(s.Attribute("Name")), (String)p.Attribute("Name") select new { SupplierName = (String)s.Attribute("Name"), ProductName = (string)p.Attribute("Name") }; foreach (var v in filtered) { Console.WriteLine("print out" + v.SupplierName, v.ProductName); } }
Keyword: XDocument,Descendants,Attribute Well, it's not quite as straightforward, because we need to tell the system how it should understand the data(in terms of what attributes should be used as what types) |
Ok, Let us put the data where it's much more likely to be- in a database. Shows how much work we have to do in LINQ to SQL Step one: Create dbml Step two: Haulage DataTable Step three: Looking
static void Main()
{ using (DataContext db = new DataContext()) { var filtered = from p in db.Products join s in db.Suppliers on p.SupplierID equals s.SupplierID where p.Price > 10 orderby s.Name, p.Name select new { SupplierName = s.Name, ProductName = p.Name }; foreach (var v in filtered) { Console.WriteLine("print out" + v.SupplierName, v.ProductName); } } } This code issues a database request, which is basically the query transalted into SQL.
For instance: => LINQ to Amazon Wow LINQ to Everything So much for this! |