<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      只為成功找方向,不為失敗找借口

      每天都不能停止前進的腳步
        博客園  :: 首頁  :: 新隨筆  :: 聯系 :: 訂閱 訂閱  :: 管理

      在使用Entity Framework加載關聯實體時,可以有三種方式:

      1.懶加載(lazy Loading);

       2.貪婪加載(eager loading);  

      3.顯示加載(explicit loading)。

      EF默認使用的是懶加載(lazy Loading)。一切由EF自動處理。

      這種方式會導致應用程序多次連接數據庫,這種情況推薦在數據量較大的情況下使用。當我們需要加載數據較少時,一次性全部加載數據會相對更高效。

      我們來看看EF的顯示加載(explicit loading)如何讓我們完全掌控數據的加載(非自動化)。

      這里我們使用Code First模式。

      數據表:商品表,商品分類表,品牌表

      Step1:新建控制臺應用程序,添加EF6引用(可以使用NuGet獲取)

       

       

      Step2:創建三個實體對象:Product、Category 、Brand

      Product實體類:

      復制代碼
       1 using System;
       2 using System.Collections.Generic;
       3 using System.Linq;
       4 using System.Text;
       5 
       6 namespace EFExplicitLoading.Models {
       7   public  class Product {
       8       public int ProductId { get; set; }
       9       public String Title { get; set; }
      10       public int CategoryId { get; set; }
      11 
      12       public virtual Category Category { get; set; }
      13 
      14       public virtual Brand Brand { get; set; }
      15 
      16   }
      17 }
      復制代碼

       

       

      Category實體類:

      復制代碼
       1 using System;
       2 using System.Collections.Generic;
       3 using System.Linq;
       4 using System.Text;
       5 
       6 namespace EFExplicitLoading.Models {
       7   public  class Category {
       8 
       9       public Category() {
      10           Products = new HashSet<Product>();
      11       }
      12 
      13       public int CategoryId { get; set; }
      14       public String Name { get; set; }
      15 
      16       public virtual ICollection<Product> Products { get; set; } 
      17   }
      18 }
      復制代碼

       

       

       

      Brand實體類:

      復制代碼
       1 using System;
       2 using System.Collections.Generic;
       3 using System.Linq;
       4 using System.Text;
       5 
       6 namespace EFExplicitLoading.Models {
       7   public  class Brand {
       8 
       9       public Brand() {
      10           Products = new HashSet<Product>();
      11       }
      12 
      13       public int BrandId { get; set; }
      14 
      15       public String Name { get; set; }
      16 
      17       public virtual ICollection<Product> Products { get; set; } 
      18   }
      19 }
      復制代碼

       

      Step3:創建派生自DbContext的類(ExplicitContext)

      復制代碼
       1 using System.Data.Entity;
       2 using EFExplicitLoading.Models;
       3 
       4 namespace EFExplicitLoading {
       5 
       6     public class ExplicitContext : DbContext {
       7         public ExplicitContext()
       8             : base("ExplicitConnectionString") {
       9         }
      10 
      11         public DbSet<Product> Products { get; set; }
      12 
      13         public DbSet<Category> Categories { get; set; }
      14 
      15         public DbSet<Brand> Brands { get; set; }
      16 
      17         protected override void OnModelCreating(DbModelBuilder modelBuilder) {
      18             modelBuilder.Entity<Product>().ToTable("Product");
      19             modelBuilder.Entity<Brand>().ToTable("Brand");
      20             modelBuilder.Entity<Category>().ToTable("Category");
      21         }
      22     }
      23 
      24 }
      復制代碼

       

      Step4:在App.config中添加connectionStrings節點

      1   <connectionStrings>
      2     <add name="ExplicitConnectionString" connectionString="Data Source=.;Initial Catalog=EFExplicit;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
      3   </connectionStrings>

       

      準備工作已就緒,當我們使用ExplicitContext類時,EF會根據實體自動創建數據庫和表

       

      下面回到控制臺入口函數處:

      Step5:添加測試數據

      復制代碼
       1 
       2             using (var context = new ExplicitContext()) {
       3                 //先清空數據
       4                 context.Database.ExecuteSqlCommand("delete from product");
       5                 context.Database.ExecuteSqlCommand("delete from brand");
       6                 context.Database.ExecuteSqlCommand("delete from category");
       7 
       8                 var category1 = new Category {Name = "服裝"};
       9                 var category2 = new Category {Name = "家電"};
      10                 var brand1 = new Brand {Name = "品牌1"};
      11                 var brand2 = new Brand {Name = "品牌2"};
      12 
      13                 context.Products.Add(new Product {Brand = brand1, Category = category1, Title = "產品1"});
      14                 context.Products.Add(new Product {Brand = brand1, Category = category2, Title = "產品2"});
      15                 context.Products.Add(new Product {Brand = brand1, Category = category2, Title = "產品3"});
      16                 context.Products.Add(new Product {Brand = brand2, Category = category2, Title = "產品4"});
      17                 context.Products.Add(new Product {Brand = brand2, Category = category2, Title = "產品5"});
      18                 context.Products.Add(new Product {Brand = brand2, Category = category2, Title = "產品6"});
      19                 context.SaveChanges();
      20             }
      復制代碼

       

       

      Step6:開始測試explicit loading

      復制代碼
       1 using (var context = new ExplicitContext()) {
       2                 //禁用懶加載
       3                 context.Configuration.LazyLoadingEnabled = false;
       4 
       5                 var category = context.Categories.First(c => c.Name == "家電");
       6 
       7                 //判斷分類關聯的產品是否已經被加載
       8                 if (!context.Entry(category).Collection(x => x.Products).IsLoaded) {
       9                     context.Entry(category).Collection(x => x.Products).Load();
      10                     Console.WriteLine("分類{0}的產品被顯示加載...", category.Name);
      11                 }
      12 
      13                 Console.Write("分類{0}下的共有{1}件產品", category.Name, category.Products.Count());
      14 
      15                 foreach (var product in context.Products) {
      16                     if (!context.Entry(product).Reference(x => x.Category).IsLoaded) {
      17                         context.Entry(product).Reference(x => x.Category).Load();
      18                         Console.WriteLine("分類{0}被顯示加載.", product.Category.Name);
      19                     }
      20                     else {
      21                         Console.WriteLine("分類{0}已經加載過了.", product.Category.Name);
      22                     }
      23                 }
      24 
      25                 //重新使用category計算 產品數量
      26                 Console.WriteLine("產品加載完后,分類{0}下有{1}件產品", category.Name, category.Products.Count());
      27 
      28                 category.Products.Clear();
      29                 Console.WriteLine("產品集合被清空了.");
      30                 Console.WriteLine("此時分類{0}下有{1}件產品", category.Name, category.Products.Count());
      31 
      32 
      33                 context.Entry(category).Collection(x => x.Products).Load();
      34                 Console.WriteLine("重新顯示加載產品");
      35                 Console.WriteLine("此時分類{0}下有{1}件產品", category.Name, category.Products.Count());
      36 
      37                 //使用ObjectContext刷新實體
      38                 var objectContext = ((IObjectContextAdapter) context).ObjectContext;
      39                 var objectSet = objectContext.CreateObjectSet<Product>();
      40                 objectSet.MergeOption = MergeOption.OverwriteChanges;
      41                 objectSet.Load();
      42                 //MergeOption.AppendOnly
      43                 //MergeOption.OverwriteChanges
      44                 //MergeOption.NoTracking
      45                 //MergeOption.PreserveChanges
      46                 
      47 
      48                 Console.WriteLine("產品集合以MergeOption.OverwriteChanges的方式重新加載");
      49                 Console.WriteLine("此時分類{0}下有{1}件產品", category.Name, category.Products.Count());
      50             }
      51 
      52 
      53             Console.WriteLine("測試部分加載...");
      54             //測試部分加載,然后加載所有
      55             using (var context = new ExplicitContext()) {
      56                 //禁用懶加載
      57                 context.Configuration.LazyLoadingEnabled = false;
      58                 var category = context.Categories.First(c => c.Name == "家電");
      59                 //先加載1條數據
      60                 Console.WriteLine("先加載1條數據");
      61                 context.Entry(category).Collection(x => x.Products).Query().Take(1).Load();
      62                 Console.WriteLine("分類{0}下共有{1}件產品", category.Name, category.Products.Count());
      63 
      64                 //加載所有
      65                 context.Entry(category).Collection(x => x.Products).Load();
      66                 Console.WriteLine("加載所有數據");
      67 
      68                 Console.WriteLine("此時分類{0}下有{1}件產品", category.Name, category.Products.Count());
      69             }
      70 
      71             Console.ReadKey();
      復制代碼

       

       

      執行結果:

        禁用懶加載(lazy loading)            

      要想測試我們的explict loading,必須先禁用懶加載,有2種方式可以禁用懶加載:

      1.設置Context.Configuration.LazyLoadingEnabled的值為false   或

      2.移除每一個實體類中的關聯實體屬性(導航屬性)的virtual訪問修飾符,這種方法可以更精確控制懶加載,即只禁用移除virtual修飾符實體的懶加載

       

        IsLoaded屬性和Load方法            

      接下來,我們利用EF獲取一條Name為家電的分類實體數據,由于Category與Product是一對多的關系,此時我們可以使用IsLoaded屬性來測試此分類下的Products集合是否被加載

      context.Entry(category).Collection(x => x.Products).IsLoaded

      若沒有加載,我們使用Load方法來加載關聯的Products,在接下來的foreach遍歷中,我們可以看到,Category關聯的Product已經全部被加載完畢

      PS:當使用Take(n)方法Load數據時,IsLoaded屬性依然為False,因為只有當關聯的所有數據加載完,IsLoaded才為true

        關系修復(relationship fixup)      

      這里Entity Framework使用稱為"關系修復"的技術(relationship fixup),即當我們單獨加載關聯實體的時候(Product),這些數據會自動掛載到已經載入的實體(Category),但這種關系修復并不是總是會生效,比如在多對多的關系中就不會這樣處理。

        關于Clear()                                 

      然后我們打印出來Category中有多少Product,之后使用Clear()方法清空category對象的關聯集合Products。

      Clear方法會移除Category和Product的關聯關系,但Product集合數據并沒有刪除,依然存在上下文的內存中,只是它不再與Category關聯。

      后面我們又重新使用Load加載Product但category.Products.Count()的值依然為0。這正好說明Clear方法的本質。

      這是因為Load默認使用MergeOption.AppendOnly的方式加載數據,找不到Product實例了(被Clear了)。然后我們使用MergeOption.OverwriteChanges的方式才將數據重新關聯

       

        關于MergeOption(實體合并選項) 

      MergeOption枚舉共有4個選項

      1.MergeOption.AppendOnly

        在現有的關系基礎上合并
      2.MergeOption.OverwriteChanges

        OverwriteChanges模式,會從數據庫中更新當前上下文實例的值(使用同一個實體對象的實例,如category)。

        當你想要恢復實體在上下文的改變,從數據庫刷新實體時,使用這個模式就非常有用。

      3.MergeOption.NoTracking

        無追蹤模式不會跟蹤對象的變化,也不會意識到對象已經被加載到當前上下文

        NoTracking可以應用到一個實體的導航屬性(關聯實體屬性),但這個實體也必須使用NoTracking

        反過來,NoTracking應用到某個實體時,這個實體的導航屬性會忽略默認的AppendOnly模式而使用NoTracking模式
      4.MergeOption.PreserveChanges

        PreserveChanges選項本質上與OverwriteChanges選項相反,

        PreserveChanges模式會更新查詢結果集(若數據庫中有變化),但不會更新在當前上下文內存中的值

      PS: 也許你已經注意到,這里我們使用了ObjectContext對象,而不是context對象,這是因為DbContext不能直接使用MergeOption類型,所以必須使用ObjectContext對象

        關于性能提升                                

      在任何時候,關聯實體集合的數量被限制時,使用Load方法,會有助于我們提升程序的性能,比如加載一個Category中的5條Product。

      在少量場景中,我們需要整個關聯集合時,也可以使用Load

      PS:當一個實體在Added(添加)、Deleted(刪除)、Detected(分離)狀態時,Load方法無法使用。

      關于Entity Framework性能提升的方法還有很多,當然,我們必須根據自己的項目實際情況來做優化。不同的應用場景,選擇不同的優化方案

       

      示例代碼:點此下載

      轉載自:http://www.rzrgm.cn/jayshsoft/p/entity-framework-explicit-loading.html

      主站蜘蛛池模板: 国产欧美日韩精品丝袜高跟鞋| 国产 另类 在线 欧美日韩| 青草青草久热精品视频在线播放| 亚洲中文精品一区二区| 亚洲成av人片不卡无码手机版| 丰满的女邻居2| 国产精品午夜福利在线观看| 体态丰腴的微胖熟女的特征| 国产女高清在线看免费观看 | 国产一区二区三区免费观看| 国产一卡2卡3卡4卡网站精品| 成人亚洲狠狠一二三四区| 樱花草视频www日本韩国| 夜夜添无码试看一区二区三区| 亚洲高清国产拍精品熟女| 91密桃精品国产91久久| 精品无码一区在线观看| 黑人大荫道bbwbbb高潮潮喷| 亚洲国产精品无码久久久| 亚洲首页一区任你躁xxxxx| 中文有无人妻vs无码人妻激烈| 欧美人与性动交α欧美精品| 久草热在线视频免费播放| 亚洲精品麻豆一区二区| 乐清市| 国产一区二三区日韩精品| 久久国产综合色免费观看| 亚洲色丰满少妇高潮18p| 一区天堂中文最新版在线| 国内不卡一区二区三区| 亚洲成人精品一区二区中| 女女互揉吃奶揉到高潮视频| 国产一区二区一卡二卡| 亚洲综合伊人久久大杳蕉| yw尤物av无码国产在线观看| 国产福利精品一区二区| 啦啦啦高清在线观看视频www | 亚洲精品中文字幕码专区| 国产精品久久久久久久9999| 厨房与子乱在线观看| 亚洲日韩国产成网在线观看|