• [Evolution in action] C#1.1=>2.0=>3.0 [LINQ and query expressions]


    Makeup Querying Collections

    filtering a collection [LINQ]

           static void Main()
           {
               List<Product> products = Product.GetSampleProducts();
               var filtered =
    from Product p in products
                                    where p.Price > 10
                                    select p;
               foreach (Product product in filtered)
               {
                   Console.WriteLine(product);
               }
           }

    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
    1
    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.

    Even though we've expressed the query in C# code, it's been executed as SQL.

    We'll see later that the way this query joins isn’t how we’d normally use LINQ to SQL— there's a more relation-oriented way of approaching it when the schema and the entities know about the relationship between suppliers and products.

    The result is the same, however, and it shows just how similar LINQ to Objects (the in-memory LINQ operating on collections) and LINQ to SQL can be.


    It's important to understand that LINQ is flexible, too: you can write your own
    query translators. It’s not easy, but it can be well worth it.

    For instance: => LINQ to Amazon

    无标题11

    Wow LINQ to Everything

    So much for this!

  • 相关阅读:
    [译]Chapter 3 Understanding Controllers
    Effiective C# Item1 : 使用属性代替成员变量
    终于出版了
    《Thinking in UML》读书笔记之一
    【译】ClickOnce部署概述
    [译]Chapter 2 Building a Simple ASP.NET MVC Application
    开始翻译《Application Architecture Guide 2.0》
    [译]Chapter 1 An Introduction to ASP.NET MVC(1)
    [译]Chapter 1 An Introduction to ASP.NET MVC(3)
    Effective C# Item4:使用Conditional特性代替#if条件编译
  • 原文地址:https://www.cnblogs.com/RuiLei/p/1166399.html
Copyright © 2020-2023  润新知