zoukankan      html  css  js  c++  java
  • Linq To Entities 及其相关

    说到Linq,很多人都非常熟悉,我们可以很方便的用它来操纵对象的集合。今天要说的是Linq To Entities及其相关的操作。下面一步一步的来进行。这里我着重强调的是语法上面的一些注意点。所以怎么通过ObjectContext生成数据库代理类,我就不说了。下面的代码就是新建一个代理类,通过这个代理类,我们可以查看所有包含的表对象及其字段:

    NorthWindEntities nWEntities = new NorthWindEntities();

    查询

    首先来说说查询操作:

      //Select records.
      IEnumerable<Product> productList = from p in nWEntities.Products
                                          select p;
      Console.WriteLine("Select Records scenario: There are {0} products",productList.Count());
      Console.WriteLine("=============================================");

    更新

    然后来说说更新操作:

     //Update records.
     Product product = productList.ElementAtOrDefault(10);
     if (product != null)
     {
         decimal newValue = (decimal)product.UnitPrice + 10;
         Console.WriteLine("Update Records scenario: before update ,the unityPrice is {0}", product.UnitPrice);
         product.UnitPrice = newValue;
         nWEntities.SaveChanges();
         Console.WriteLine("Update Records scenario: after update, the unityPrice is {0}",product.UnitPrice);
     }
     Console.WriteLine("=============================================");

    注意这里我们利用的是SaveChanges方法进行提交。

    插入

    然后来说说插入操作:

    //Insert records
    Product newProduct = new Product() { ProductName = "This is new product" };
    nWEntities.Products.AddObject(newProduct);
    nWEntities.SaveChanges();
    Product retriveNewProduct = nWEntities.Products.Where(p => p.ProductName == "This is new product").FirstOrDefault();
    Console.WriteLine("Insert records scenario: after insert, the new product name is {0} ",retriveNewProduct.ProductName);
    Console.WriteLine("=============================================");

    删除

    然后就是删除操作:

     //Delete records
    Product productForDelete = nWEntities.Products.Where(p => p.ProductName == "This is new product").FirstOrDefault();
     nWEntities.Products.DeleteObject(productForDelete);
     nWEntities.SaveChanges();
     Console.WriteLine("Delete records scenario: the product with id {0} has been deleted.", productForDelete.ProductID);
     Console.WriteLine("=============================================");
     

    上面就是整个CRUD的代码,内容我就不多说了。由于Linq To Entities为我们生成了CRUD的方法,所以我们直接调用后,利用SaveChanges方法即可将结果保存到数据库。

    接下来要说明的是延缓执行,早绑定,晚绑定以及表连接的内容。

    延缓执行

    对于延缓执行(Deferred Execution),其实就是指数据真正被需要的时候,才去数据库拿,而不是说Linq一准备好,就直接去数据库拿数据,这样对数据库造成的压力是不小的。

    //Test Deferred Execution(延缓执行)
      IQueryable<Product> productOnDeferredExecution = from p in nWEntities.Products
                                                       where p.Category.CategoryName == "This is new product"
                                                       orderby p.ProductName
                                                       select p;
      //下面才真正被执行
      Console.WriteLine("Deferred Execution scenario: Totally {0} products", productOnDeferredExecution.Count());
      Console.WriteLine("=============================================");
    
      //Test Deferred Execution1(延缓执行1)
      //下面这句就已经被真正执行
      decimal? averagePrice = (from p in nWEntities.Products select p.UnitPrice).Average();
      Console.WriteLine("Deferred Execute scenario for single object:  The average price is {0}", averagePrice);
      Console.WriteLine("=============================================");
    
      //Test Deferred Execution2(延缓执行,稍微复杂一点)
      var cheapestProductsByCategory =
                                         from p in nWEntities.Products
                                         group p by p.CategoryID into g
                                         select new
                                         {
                                             CategoryID = g.Key,
                                             CheapestProduct =
                                                              from p2 in g
                                                                where p2.UnitPrice == g.Min(p3 => p3.UnitPrice)
                                                              select p2).FirstOrDefault()
                                         };
      Console.WriteLine("Deferred Execute scenario: Cheapest Products are:");
      //遇到Foreach的时候,才被执行
      foreach (var tP in cheapestProductsByCategory)
      {
          if (tP.CategoryID != null && tP.CheapestProduct != null)
              Console.WriteLine("category:{0} | product name: {1} | price: {2}", tP.CategoryID, tP.CheapestProduct.ProductName, tP.CheapestProduct.UnitPrice);
      }
      Console.WriteLine("=============================================");

    对于代码段1,只有当productOnDeferredExecution.Count()被调用的时候,程序才从数据库获取数据;

    对于代码段2,由于获取出来的直接是decimal类型,所以当程序走到decimal? averagePrice = (from p ).Average(); 的时候,程序已经开始去数据库获取数据了。

    对于代码段3,由于获取出来的cheapestProductsByCategory 是IQueryable类型,所以只有当代码执行到Foreach的时候,程序才开始从数据库中去取数据。

    晚绑定

    而说到晚绑定(Lazy loading),则是指我只有需要某个表中的数据的时候,才去数据库拿,而不是在先期直接把所有涉及到的表的数据都给拿出来:

      //Lazy Loading(晚绑定)
      var categories = from c in nWEntities.Categories select c;
      //当循环执行的时候,每循环一次,EF就自动去数据库执行一次数据查询
      foreach (var category in categories)
      {
          Console.WriteLine(" Lazy Loading scenario: There are {0} products in category {1}",category.Products.Count,category.CategoryName);
      }
      Console.WriteLine("=============================================");
    

    在上面代码中,当遇到Foreach的时候,程序才开始去数据库中拿数据,并且在每次循环中,程序都会去数据拿一次数据。这个可以在Sql Profile中最追踪到。比如我当前有8个category,那么在8次循环中,程序将访问8次数据库,以便拿到合适的数据。

    早绑定

    说到早绑定(Eager loading),则与上面相反,他是指,把所有相关联的表的数据在先期都提取出来,省去了频繁往返数据库的麻烦。这里我们可以通过include关键字将涉及的表全部绑定起来:

    //Eager Loading (早绑定)
    //利用Include可以让查询把需要的表给提前包含进来。这样就不必每循环一次,就查询一次数据库
    var categoriesOnEagerLoading = from c in nWEntities.Categories.Include("Products") select c;
    foreach (var category in categoriesOnEagerLoading)
    {
        Console.WriteLine(" Eager Loading scenario: There are {0} products in category {1}", category.Products.Count, category.CategoryName);
    }
    Console.WriteLine("=============================================");
    

    在上面代码中,我们利用Include("Products")语句将Products表中的数据也绑定进来,在下面Foreach的时候,程序就不用再循环返回数据库获取数据了。

    我们可以同时通过Include("Products").Include("***")来加入多张需要提前绑定的表。

    表连接

    说到JoinTable,我们就不用多费口舌了,具体说来就是通过Join关键字来实现:

    //Join Tables
    var categoriesProducts = from c in nWEntities.Categories
                             join p in nWEntities.Products
                             on c.CategoryID equals p.CategoryID
                             into productsByCategoryID
                             select new
                             {
                                 c.CategoryName,
                                 productCount = productsByCategoryID.Count()
                             };
    foreach (var p in categoriesProducts)
    {
        Console.WriteLine("Join tables scenario: There are {0} products in category {1}",p.productCount,p.CategoryName);
    }
    

    执行结果

    最后来看下输出结果:

    QQ截图20131106193521

    源码下载

    点击这里下载


     



     


    
    
  • 相关阅读:
    斗鱼的sidebar的实现简陋的demo
    angular JS中使用jquery datatable添加checkbox点击事件
    angular JS中使用jquery datatable添加ng-click事件
    Redis 中文文档
    操作word的
    Redis作为消息队列服务场景应用案例(入队和出队)
    nopcommerce 商城案例
    net 将手机号码中间的数字替换成星号
    V5客服
    EF 数据库迁移(Migration)
  • 原文地址:https://www.cnblogs.com/scy251147/p/3411155.html
Copyright © 2011-2022 走看看