zoukankan      html  css  js  c++  java
  • Note introducting LINQ

     LINQ is a methodology that simplifies and unifies the implenentation of any kind of data access.  It offering a uniform way to access and manage data without forcing the adoption
    of a "one size fies all" model.  It is a programming model that introduces queries as a
    first-class concept into any Microsoft.Net language.However, complete support for LINQ
    requires some extensions int the language used.  These extensions boost productivity, thereby
    providing a shorter, meaningful, and expressive syntax to manipulate data.

    A simple LINQ query for a typical software solution that returns the names of customers in Italy:

    var query = 
        from   c 
    in Customers
        
    where  c.Country == "Italy"
        select c.CompanyName;

    foreach(string name in query) {
        Console.WriteLine( name );
    }

    The result of this query is a list of stirngs.  You can enumerate these values with a
    foreach loop in C#.

    *The same query(and the following foreach code) can be applied to an SQL database,to a DataSet, to an array of object in memory,or to many other kinds of data. Customers could
    be a collection of objects.

    Like this:

    Customer[] Customers;

    DataDet ds 
    = GetDataSet();

    DataTable Customers 
    = ds.Tables["Customers"];

    Customers could be an entity class that describies a physical table in a relational database.

    DataContext db = new DataContext(ConnectionString);
    Table<Customer> Customers = db.GetTable<Customer>();

    describies a conceptual model and is mapped to a relational database.

    NorthwindModel dataModel = new NorehwindModel();
    ObjectQuery<Customer> Customers = dataModel.Customers;


    Customer[]Customers=GetCustomers();
    varquery=
    fromcinCustomers
    wherec.Country=="Italy"
    selectc;

    the compiler generates this code:

    Customer[]Customers=GetCustomers();
    IEnumerable<Customer>query=
    Customers
    .Where(c=>c.Country=="Italy");

    becomes longer, as you see here:
    varquery=
    fromcinCustomers
    wherec.Country=="Italy"
    orderbyc.Name
    selectnew{c.Name,c.City};
    the generated code is longer too:
    var query=
    Customers
    .Where(c=>c.Country=="Italy");
    .OrderBy(c=>c.Name)
    .Select(c=>new{c.Name,c.City});

    The code apparently calls instance members on the object returaned from the previous

    The Var keyword used to declare query infers the variable type declaration from the initial
    assignment,which in this case will return an IEnumerable<T> type.

    *The important concept is the timing of operations over data.In general,a LINQ query is
    not really executed until there is access to the query result,because it describies a set
    of operations that will be performed when necessary.
    The access to a query result does the real work.

    This can be illustrated in the case of a foreach loop:
    varquery=fromcinCustomers...
    foreach (stringnameinquery)...
    There are also methods that iterate a LINQ query result, producing a persistent copy of data
    in memory. For example, the ToList method produces a typed List<T> collection:
    varquery=fromcinCustomers...
    List<Customer>customers= query.ToList();
    When the LINQ query operates on data that is on a relational database (such as Microsoft
    SQL Server), the LINQ query generates an equivalent SQL statement instead of operating
    with in-memory copies of data tables. The query execution on the database is delayed until
    the first access to the query result. Therefore, if in the last two examples Customers was a
    Table<Customer> type (a physical table in a relational database) or an ObjectQuery<Customer>
    type (a conceptual entity mapped to a relational database), the equivalent SQL query would
    not be sent to the database until the foreach loop was executed or the ToList method was
    called. The LINQ query can be manipulated and composed in different ways until that time.


    At first sight, LINQ might appear to be just another SQL dialect. This similarity has its roots in
    the way a LINQ query can describe a relationship between entities such as an SQL join:
    varquery=
    fromcinCustomers
    joinoinOrders
    onc.CustomerIDequalso.CustomerID
    selectnew{c.CustomerID,c.CompanyName,o.OrderID};

    var query =
                  from   c in Customers
                  join   s in Suppliers
                         on c.City equals s.City
                  select new { c.City, c.Name, SupplierName = s.Name };

             And something like the following will be returned:

              City=Torino     Name=Marco       SupplierName=Trucker
              City=Dallas     Name=James       SupplierName=FastDelivery
              City=Dallas     Name=James       SupplierName=Horizon
              City=Seattle    Name=Frank       SupplierName=WayFaster

    When you build a LINQ query,it is always a set of Operations on instances of some classes.

        Note    You can create entity classes by using code-generation tools such as SQLMetal or
                 the LINQ to SQL Designer in Microsoft Visual Studio.

              In Listing 1-3, you can see an example of a Product class that maps a relational table named
              Products, with five columns that correspond to public data members.

              Listing 1-3  Class declaration mapped on a database table

                 [Table("Products")]
                 public class Product {
                     [Column(IsPrimaryKey=true)] public int IdProduct;
                     [Column(Name="UnitPrice")] public decimal Price;
                     [Column()] public string ProductName;
                     [Column()] public bool Taxable;
                     [Column()] public decimal Tax;
                 }
    When you work on entities that describe external data (such as database tables), you can
              create instances of these kinds of classes and manipulate in-memory objects just as if data
              from all tables were loaded in memory. These changes are submitted to the database through
              SQL commands when you call the SubmitChanges method, as you can see in Listing 1-4.

              Listing 1-4  Database update calling the SubmitChanges method

              

       var taxableProducts = 
                     from   p 
    in db.Products 
                     
    where  p.Taxable == true 
                     select p; 
                 
    foreach( Product product in taxableProducts ) 
                     RecalculateTaxes( product ); 
                 }
     
                 db.SubmitChanges(); 

              The Product class in the preceding example represents a row in the Products table of an
              external database. When SubmitChanges is called, all changed objects generate an SQL
              command to update the corresponding rows in the table.

    LINQ has a different set of classes and extensions to support the manipulation of XML data.
    Imagine that your customers are
              able to send orders using XML files like the ORDERS.XML file shown in Listing 1-5.

              Listing 1-5  A fragment of an XML file of orders

                 <?xml version="1.0" encoding="utf-8" ?> 
                 
    <orders xmlns="http://schemas.devleap.com/Orders"> 
                     
    <order idCustomer="ALFKI" idProduct="1" quantity="10" price="20.59"/> 
                     
    <order idCustomer="ANATR" idProduct="5" quantity="20" price="12.99"/> 
                     
    <order idCustomer="KOENE" idProduct="7" quantity="15" price="35.50"/> 
                 
    </orders> 


    *Using standard Microsoft .NET 2.0 System.Xml classes,you can load the file using a DOM
    approach or you can parse its contents using an XmlReader implementation.
    If you need to extract all the products ordered with their quantities, you can parse the orders
              file using an XmlReader to accomplish this, as shown in Listing 1-6.

              Listing 1-6  Reading the XML file of orders using anXmlReader

                 String nsUri = "http://schemas.devleap.com/Orders";
                 XmlReader xmlOrders = XmlReader.Create( "Orders.xml" );

        

             List<Order> orders = new List<Order>(); 
                 Order order 
    = null
                 
    while (xmlOrders.Read()) 
                     
    switch (xmlOrders.NodeType) 
                         
    case XmlNodeType.Element: 
                              
    if ((xmlOrders.Name == "order"&& 
                              (xmlOrders.NamespaceURI 
    == nsUri)) 
                                  order 
    = new Order(); 
                                  order.CustomerID 
    = xmlOrders.GetAttribute( "idCustomer" ); 
                                  order.Product 
    = new Product(); 
                                  order.Product.IdProduct 
    = 
                                      Int32.Parse( xmlOrders.GetAttribute( 
    "idProduct" ) ); 
                                  order.Product.Price 
    = 
                                      Decimal.Parse( xmlOrders.GetAttribute( 
    "price" ) ); 
    Introducing Microsoft LINQ 

                                 order.Quantity 
    = 
                                      Int32.Parse( xmlOrders.GetAttribute( 
    "quantity" ) ); 
                                 orders.Add( order ); 
                             }
     
                             
    break
                     }
     
                 }
     

              You could also use an XQuery like the following one to select nodes:

              for $order in document("Orders.xml")/orders/order
              return $order

    shows a LINQ to XML query made over the orders file.

              Listing 1-7  Reading the XML file using LINQ to XML

                 XDocument xmlOrders = XDocument.Load( "Orders.xml" ); 

                 XNamespace ns 
    = "http://schemas.devleap.com/Orders"
                 var orders 
    = from o in xmlOrders.Root.Elements( ns + "order" ) 
                              select 
    new Order { 
                                          CustomerID 
    = (String)o.Attribute( "idCustomer" ), 
                                          Product 
    = new Product { 
                                              IdProduct 
    = (Int32)o.Attribute("idProduct"), 
                                              Price 
    = (Decimal)o.Attribute("price") }, 
                                          Quantity 
    = (Int32)o.Attribute("quantity"
                                      }; 

    In SQL, you can write the following:

              SELECT * FROM Customers WHERE Country = 'Italy'

              In C#, you would probably write this:

              public List<Customer> ItalianCustomers( Customer customers[] )
               {
                  List<Customer> result = new List<Customer>();
                  foreach( Customer c in customers ) {
                      if (c.Country == "Italy") result.Add( c );
                  }
                  return result;
              }

    IEnumerable<T> interface. You can use LINQ to write a query over Reflection:

    var query =
        from     assembly in AppDomain.CurrentDomain.GetAssemblies()
        from     type in assembly.GetTypes()
        from     method in type.GetMethods()
        where    method.IsStatic
                 && method.ReturnType.GetInterface( "IEnumerable`1" ) != null
        orderby method.DeclaringType.Name, method.Name
        group    method by new { Class = method.DeclaringType.Name,
                                  Method = method.Name };

    The equivalent C# code that handles data is longer to write, harder to read, and probably more
    error prone. You can see a possible version that is not particularly optimized in Listing 1-10.

    Listing 1-10  C# code equivalent to a LINQ query over Reflection

       

    List<String> results = new List<string>(); 
       
    foreach( var assembly in AppDomain.CurrentDomain.GetAssemblies()) 
           
    foreach( var type in assembly.GetTypes() ) 
                
    foreach( var method in type.GetMethods()) 
                    
    if (method.IsStatic && 
                        method.ReturnType.GetInterface(
    "IEnumerable`1"!= null
                        
    string fullName = String.Format( "{0}.{1}"
                                               method.DeclaringType.Name, 
                                               method.Name ); 
                        
    if (results.IndexOf( fullName ) < 0
                            results.Add( fullName ); 
                        }
     
                    }
     
                }
     
           }
     
       }
     

       results.Sort();
    Many possible evolutions could originate form LINQ, and we should not forget that SQL is a
    widely adepted standard that cannot be easily replaced by another.

    extension  [ex·ten·sion || ɪk'stenʃn]
    n.  延长, 范围, 扩充
    boost  [buːst]
    n.  推进, 增加, 支援
    v.  举, 抬; 推动; 推; 促进
    thereby 
    adv.  因此, 在那方面, 从而
    expressive  [ex·pres·sive || ɪk'spresɪv]
    adj.  表达的
    syntax  [syn·tax || 'sɪntæks]
    n.  语法; 有条理的排列; 句法
    manipulate  [ma·nip·u·late || mə'nɪpjəleɪt /-jʊl-]
    v.  操纵, 操作, 利用
    typical  [typ·i·cal || 'tɪpɪkl]
    adj.  典型的, 象征性的
    entity  [en·ti·ty || 'entətɪ]
    n.  实体; 本质; 存在
    compiler  [com·pil·er || kəm'paɪlə]
    n.  从高级语言原始码制造程序的程序 (计算机用语); 编辑者; 编译器
    from now on 
    从现在开始
    domain  [do·main || dəʊ'meɪn]
    n.  领土; 范围; 领地, 自治区; 因特网根据国家和组织类型的分类 (计算机用语)
    instance  [in·stance || 'ɪnstəns]
    n.  例证, 情况, 建议
    v.  引以为例, 获得例证
    declare  [de·clare || dɪ'kleə]
    v.  断言; 宣布; 宣称; 声明, 表示
    concept  [con·cept || 'kɒnsept]
    n.  观念; 概念
    preform  ['prɪː'fɔrm /-'fɔːm]
    v.  预先形成
    manipulation  [ma·nip·u·la·tion || mə'nɪpjəleɪʃn /-jʊl-]
    n.  处理; 操纵; 操作
    parse  [pɑrz/pɑː-]
    v.  解析; 符合语法
    n.  分列, 为使程序处理容易而把输入分成小部分 (计算机用语)
    evolution  [ev·o·lu·tion || ‚iːvə'luːʃn]
    n.  进化, 进展, 发展
    adept  [ad·ept || 'ædept]
    adj.  熟练的, 内行的; 拿手的
    n.  内行, 老手, 擅长者; 专家

  • 相关阅读:
    http://maxie.cnblogs.com/
    有一种爱叫错过
    Lotuser进阶系列(转)——多目录环境中的单点登陆1
    DOMINO中实现PDF在线编辑控件 and so on......(三)
    DOMINO中实现PDF在线编辑控件 and so on......(一)
    Lotuser进阶系列(转)——多目录环境中的单点登陆2
    在两个代理之间传递参数
    利用 DSAPI 为 Domino Web 用户定制用户名和口令认证
    通过 Lotus Domino Java 代理消费 Web 服务
    代理中如何获取参数么?
  • 原文地址:https://www.cnblogs.com/williamzhao/p/2410619.html
Copyright © 2011-2022 走看看