最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Entity Framework加載控制Loading Entities

 更新時(shí)間:2022年03月05日 11:49:12   作者:.NET開發(fā)菜鳥  
本文詳細(xì)講解了Entity Framework加載控制Loading Entities的用法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

Entity Framework允許控制對象之間的關(guān)系,在使用EF的過程中,很多時(shí)候我們會(huì)進(jìn)行查詢的操作,當(dāng)我們進(jìn)行查詢的時(shí)候,哪些數(shù)據(jù)會(huì)被加載到內(nèi)存中呢?所有的數(shù)據(jù)都需要嗎?在一些場合可能有意義,例如:當(dāng)查詢的實(shí)體僅僅擁有一個(gè)相關(guān)的子實(shí)體時(shí)可以加載所有的數(shù)據(jù)到內(nèi)存中。但是,在多數(shù)情況下,你可能并不需要加載全部的數(shù)據(jù), 而是只要加載一部分的數(shù)據(jù)即可。

默認(rèn)情況下,EF僅僅加載查詢中涉及到的實(shí)體,但是它支持兩種特性來幫助你控制加載:

  • 1、貪婪加載
  • 2、延遲加載

下面以客戶類型、客戶和客戶郵件三個(gè)實(shí)體之間的關(guān)系來講解兩種加載方式。

從上圖可以看出三個(gè)實(shí)體類之間的關(guān)系:

客戶類型和客戶是一對多的關(guān)系:一個(gè)客戶類型可以有多個(gè)客戶。
客戶和客戶郵件是一對一的關(guān)系:一個(gè)客戶只有一個(gè)郵箱地址。(假設(shè)只有一個(gè)郵箱地址)

一、延遲加載(Lazy Loading)

延遲加載:即在需要或者使用的時(shí)候才會(huì)加載數(shù)據(jù)。默認(rèn)情況下,EF使用延遲加載的方式來加載數(shù)據(jù)。延遲加載是這樣一種過程:直到LINQ查詢的結(jié)果被枚舉時(shí),該查詢涉及到的相關(guān)實(shí)體才會(huì)從數(shù)據(jù)庫加載。如果加載的實(shí)體包含了其他實(shí)體的導(dǎo)航屬性,那么直到用戶訪問該導(dǎo)航屬性時(shí),這些相關(guān)的實(shí)體才會(huì)被加載。

使用延遲加載必須滿足兩個(gè)條件:
1、實(shí)體類是由Public修飾符修飾的,不能是封閉類。
2、導(dǎo)航屬性標(biāo)記為Virtual。

1、定義實(shí)體類

CustomerType實(shí)體類定義如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LazyLoding.Model
{
    public class CustomerType
    {
        public int CustomerTypeId { get; set; }
        public string Description { get; set; }

        // 導(dǎo)航屬性使用virtual關(guān)鍵字修飾,用于延遲加載
        public virtual ICollection<Customer> Customers { get; set; }
    }
}

Customer實(shí)體類定義如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LazyLoding.Model
{
    public class Customer
    {
        public int CustomerId { get; set; }
        public string Name { get; set; }

        // 導(dǎo)航屬性使用virtual關(guān)鍵字修飾,用于延遲加載
        public virtual CustomerType CustomerType { get; set; }
        // 導(dǎo)航屬性使用virtual關(guān)鍵字修飾,用于延遲加載
        public virtual CustomerEmail CustomerEmail { get; set; }
    }
}

CustomerEmail實(shí)體類定義如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LazyLoding.Model
{
    public class CustomerEmail
    {
        public int CustomerEmailId { get; set; }
        public string Email { get; set; }
        // 導(dǎo)航屬性使用virtual關(guān)鍵字修飾,用于延遲加載
        public virtual Customer Customer { get; set; }
    }
}

2、定義數(shù)據(jù)上下文類,并配置實(shí)體關(guān)系

using LazyLoding.Model;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LazyLoding.EF
{
    public class Context :DbContext
    {
        public Context()
            : base("name=AppConnection")
        {

        }

        #region 將領(lǐng)域?qū)嶓w添加到DbSet中
        public DbSet<CustomerType> CustomerTypes { get; set; }
        public DbSet<Customer> Customers { get; set; }
        public DbSet<CustomerEmail> CustomerEmails { get; set; }
        #endregion

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            // 設(shè)置表名和主鍵
            modelBuilder.Entity<CustomerType>().ToTable("CustomerType").HasKey(p => p.CustomerTypeId);
            modelBuilder.Entity<Customer>().ToTable("Customer").HasKey(p => p.CustomerId);
            modelBuilder.Entity<CustomerEmail>().ToTable("CustomerEmail").HasKey(p => p.CustomerEmailId);

            // 設(shè)置實(shí)體關(guān)系
            /*
             配置一對多關(guān)系
             HasMany:表示一個(gè)CustomerType里面包含多個(gè)Customers
             WithRequired:表示必選,CustomerType不能為空
             MapKey:定義實(shí)體之間的外鍵
             */
            modelBuilder.Entity<CustomerType>().HasMany(p => p.Customers).WithRequired(t => t.CustomerType)
                .Map(m =>
                {
                    m.MapKey("CustomerTypeId");
                });

            /*
             配置一對一的關(guān)系
             HasRequired:表示前者必選包含后者,前者可以獨(dú)立存在,后者不可獨(dú)立存在
             WithRequiredPrincipal:指明實(shí)體的主要 這里表示指定Customer表是主表可以獨(dú)立存在
             MapKey:定義實(shí)體之間的外鍵
             */
            modelBuilder.Entity<Customer>().HasRequired(p => p.CustomerEmail).WithRequiredPrincipal(t => t.Customer)
                .Map(m =>
                {
                    m.MapKey("CustomerId");
                });
            base.OnModelCreating(modelBuilder);
        }
    }
}

3、使用數(shù)據(jù)遷移生成數(shù)據(jù)庫,并重寫Configuration類的Seed()方法填充種子數(shù)據(jù)

Configuration類定義如下:

namespace LazyLoding.Migrations
{
    using LazyLoding.Model;
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<LazyLoding.EF.Context>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(LazyLoding.EF.Context context)
        {
            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet<T>.AddOrUpdate() helper extension method
            //  to avoid creating duplicate seed data.

            // 初始化種子數(shù)據(jù)
            context.CustomerTypes.AddOrUpdate(
                new CustomerType()
                {
                    Description = "零售",
                    Customers = new List<Customer>()
                     {
                       new Customer(){Name="小喬", CustomerEmail=new CustomerEmail(){ Email="qiao@qq.com"}},
                       new Customer(){Name="周瑜",CustomerEmail=new CustomerEmail(){Email="yu@126.com"}}
                     }
                },
                new CustomerType()
                {
                    Description = "電商",
                    Customers = new List<Customer>()
                  {
                    new Customer(){Name="張飛", CustomerEmail=new CustomerEmail(){Email="zf@qq.com"}},
                    new Customer(){Name="劉備",CustomerEmail=new CustomerEmail(){Email="lb@163.com"}}
                  }
                }
                );
        }
    }
}

4、查看生成的數(shù)據(jù)庫

5、查看Main方法,并打開SQL Server Profiler監(jiān)視器監(jiān)視數(shù)據(jù)庫

// 還沒有查詢數(shù)據(jù)庫
var customerType = dbContext.CustomerTypes;

繼續(xù)執(zhí)行

查看監(jiān)視器:

發(fā)現(xiàn)這時(shí)候產(chǎn)生了查詢的SQL語句。

這就是EF的延遲加載技術(shù),只有在數(shù)據(jù)真正用到的時(shí)候才會(huì)去數(shù)據(jù)庫中查詢。

使用Code First時(shí),延遲加載依賴于導(dǎo)航屬性的本質(zhì)。如果導(dǎo)航屬性是virtual修飾的,那么延遲加載就開啟了,如果要關(guān)閉延遲加載,不要給導(dǎo)航屬性加virtual關(guān)鍵字就可以了。

注意:如果想要為所有的實(shí)體關(guān)閉延遲加載,那么可以在Context的構(gòu)造函數(shù)中配置關(guān)閉屬性即可,代碼如下:

public Context() : base("name=AppConnection")
{
      // 配置關(guān)閉延遲加載
      this.Configuration.LazyLoadingEnabled = false;
}

二、貪婪加載(Eager Load)

貪婪加載:顧名思義就是一次性把所有數(shù)據(jù)都加載出來。貪婪加載是這樣一種過程:當(dāng)我們要加載查詢中的主要實(shí)體時(shí),同時(shí)也加載與之相關(guān)的所有實(shí)體。要實(shí)現(xiàn)貪婪加載,我們要使用Include()方法。

下面我們看一下如何在加載Customer數(shù)據(jù)的時(shí)候,同時(shí)也加載所有的CustomerType數(shù)據(jù)(操作此功能時(shí)暫時(shí)先關(guān)閉延遲加載以免影響)。

//貪婪加載,以下兩種方式都可以 
// 在使用Lambda表達(dá)式指明要加載的導(dǎo)航實(shí)體時(shí),要引用命名空間:System.Data.Entity
var customers = dbContext.Customers.Include(p => p.CustomerType).Include(p => p.CustomerEmail).ToList();
//方式2
var query = dbContext.Customers.Include("CustomerType").Include("CustomerEmails");

總結(jié):

貪婪加載:

  • 1、減少數(shù)據(jù)訪問的延遲,在一次數(shù)據(jù)庫的訪問中返回所有的數(shù)據(jù)。
  • 2、一次性加載所有的數(shù)據(jù)到內(nèi)存中,可能導(dǎo)致部分?jǐn)?shù)據(jù)實(shí)際用不到,從而導(dǎo)致讀取數(shù)據(jù)的速度變慢,效率變低。

延遲加載:

  • 1、只在需要讀取關(guān)聯(lián)數(shù)據(jù)的時(shí)候才進(jìn)行加載。每一條數(shù)據(jù)都會(huì)訪問一次數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫的壓力加大。
  • 2、可能因?yàn)閿?shù)據(jù)訪問的延遲而降低性能,因?yàn)檠h(huán)中,每一條數(shù)據(jù)都會(huì)訪問一次數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫的壓力增大。

如何選擇使用哪種查詢機(jī)制:

  • 1、如果是在foreach循環(huán)中加載數(shù)據(jù),那么使用延遲加載會(huì)比較好,因?yàn)椴恍枰淮涡詫⑺袛?shù)據(jù)都讀取出來,這樣雖然可能會(huì)造成多次查詢數(shù)據(jù)庫,但基本上在可以接受的范圍之內(nèi)。
  • 2、如果在開發(fā)時(shí)就可以預(yù)見需要一次性加載所有的數(shù)據(jù),包含關(guān)聯(lián)表的所有數(shù)據(jù),那么使用貪婪加載是比較好的選擇,但是此種方式會(huì)導(dǎo)致效率問題,尤其是在數(shù)據(jù)量大的情況下。

代碼下載地址:點(diǎn)此下載

到此這篇關(guān)于Entity Framework加載控制Loading Entities的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • asp.net core 集成swagger ui的原理解析

    asp.net core 集成swagger ui的原理解析

    本文主要講解了如何對API進(jìn)行分組,這里僅僅是舉了一個(gè)按照API功能進(jìn)行分組的例子,其實(shí)在實(shí)際開發(fā)中,要按照何種方式分組,可以按照需求靈活定義,比如按照API版本進(jìn)行分組
    2021-10-10
  • 使用C#處理WebBrowser控件在不同域名中的跨域問題

    使用C#處理WebBrowser控件在不同域名中的跨域問題

    我們在做web測試時(shí),經(jīng)常會(huì)使用WebBrowser來進(jìn)行一些自動(dòng)化的任務(wù)而有些網(wǎng)頁上面會(huì)用IFrame去嵌套別的頁面,這些頁面可能不是在相同域名下的,這時(shí)就會(huì)出現(xiàn)跨域問題,無法直接在WebBrowser中獲取到IFrame中的元素,接下來介紹如何解決此問題,需要了解的朋友可以參考下
    2012-12-12
  • ASP.NET?Core?6.0?添加?JWT?認(rèn)證和授權(quán)功能

    ASP.NET?Core?6.0?添加?JWT?認(rèn)證和授權(quán)功能

    這篇文章主要介紹了ASP.NET?Core?6.0?添加?JWT?認(rèn)證和授權(quán),本文將分別介紹?Authentication(認(rèn)證)?和?Authorization(授權(quán)),通過實(shí)例代碼分別介紹了這兩個(gè)功能,需要的朋友可以參考下
    2022-04-04
  • ASP.NET Session的七點(diǎn)認(rèn)識(shí)小結(jié)

    ASP.NET Session的七點(diǎn)認(rèn)識(shí)小結(jié)

    ASP.NET Session的使用當(dāng)中我們會(huì)遇到很多的問題,那么這里我們來談下經(jīng)常出現(xiàn)的一些常用ASP.NET Session的理解
    2011-07-07
  • asp.net實(shí)現(xiàn)拒絕頻繁的IP訪問的方法

    asp.net實(shí)現(xiàn)拒絕頻繁的IP訪問的方法

    這篇文章主要介紹了asp.net實(shí)現(xiàn)拒絕頻繁的IP訪問的方法,涉及asp.net針對訪問IP的判斷及配置文件的設(shè)置技巧,需要的朋友可以參考下
    2016-04-04
  • 剖析Asp.Net路由系統(tǒng)實(shí)現(xiàn)原理

    剖析Asp.Net路由系統(tǒng)實(shí)現(xiàn)原理

    本篇文章主要介紹了剖析Asp.Net路由系統(tǒng)實(shí)現(xiàn)原理,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-02-02
  • 理解ASP.NET?Core?錯(cuò)誤處理機(jī)制(Handle?Errors)

    理解ASP.NET?Core?錯(cuò)誤處理機(jī)制(Handle?Errors)

    這篇文章主要介紹了理解ASP.NET?Core?錯(cuò)誤處理(Handle?Errors)?,在這里需要注意的是,與“異常處理”有關(guān)的中間件,一定要盡早添加,這樣,它可以最大限度的捕獲后續(xù)中間件拋出的未處理異常。感興趣的朋友跟隨小編一起看看吧
    2021-11-11
  • Asp.Net在線預(yù)覽Word文檔的解決方案與思路詳解

    Asp.Net在線預(yù)覽Word文檔的解決方案與思路詳解

    這篇文章主要介紹了Asp.Net在線預(yù)覽Word文檔的解決方案與思路,大致思路是先將Word文檔轉(zhuǎn)換Html,再預(yù)覽Html,需要注意電腦安裝Office,需要的朋友可以參考下
    2022-04-04
  • ASP.NET GridView的Bootstrap分頁樣式

    ASP.NET GridView的Bootstrap分頁樣式

    這篇文章主要為大家詳細(xì)介紹了ASP.NET GridView的Bootstrap分頁樣式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • 一步一步學(xué)asp.net Ajax登錄設(shè)計(jì)實(shí)現(xiàn)解析

    一步一步學(xué)asp.net Ajax登錄設(shè)計(jì)實(shí)現(xiàn)解析

    做一個(gè)登錄,擁有自動(dòng)記住賬號(hào)和密碼的功能,要保證安全性,ajax,無刷新,良好的用戶體驗(yàn).(母板頁)
    2012-05-05

最新評(píng)論

汶川县| 东源县| 和林格尔县| 饶阳县| 保靖县| 井陉县| 霍邱县| 林周县| 清原| 英山县| 景谷| 大丰市| 长泰县| 邵东县| 芦山县| 河池市| 凌云县| 平武县| 阆中市| 大渡口区| 安康市| 永寿县| 兴海县| 南投市| 鄂伦春自治旗| 宁国市| 安图县| 澜沧| 秦安县| 南江县| 莲花县| 鄂伦春自治旗| 淳安县| 晋城| 城市| 德昌县| 文登市| 灵丘县| 勐海县| 崇义县| 工布江达县|