亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

MVC系列學習(三)-EF的延遲加載

2019-11-17 02:25:57
字體:
來源:轉載
供稿:網友

MVC系列學習(三)-EF的延遲加載

1.什么叫延遲加載

字面上可以理解為,一個動作本該立即執行的動作,沒有立即執行

2.從代碼上理解

static void Main(string[] args){    //執行該語句的時候,查看sql監視器,發現并沒有生成sql語句    IEnumerable<Student> stu = dbContext.Students.Where(s => s.Id == 1).Select(s => s);    //只有當  使用的時候  ,才生成sql語句    Student student = stu.FirstOrDefault();}

只有對象被使用了,才生成sql語句

3.尋找原因,什么原因導致延遲加載

先理解兩個Where()方法:

a.集合的Where()

List<string> listStr = new List<string>(){    "A",    "BB",    "CCC"};string  bb = listStr.Where(s => s.Length == 2).Select(s => s).FirstOrDefault();

轉到Where的定義,發現 集合 中的Where方法 實際上是IEnumerable的擴展方法,該接口繼承與IEnumerable

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> PRedicate);
public interface IEnumerable<out T> : IEnumerable

b.DbSet中的Where方法

dbContext.Students是DbSet<Student>類型,所以此處說 DbSet的中Where方法

var stu = dbContext.Students.Where(s => s.Id == 1);
public partial class SchoolEntities : DbContext{    public virtual DbSet<Student> Students { get; set; }}

image

dbContext.Students是DbSet<T>類型的,轉到DbSet<T>定義看看

此處的Where()是IQueryable的擴展方法,繼承與IQueryable

public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);
public interface IQueryable<out T> : IEnumerable<T>, IQueryable, IEnumerable
public interface IQueryable : IEnumerable

 

c.IEnumerable與IQueryable的區別

var s1 = dbContext.Students.Where(s => s.Id == 1); var s2 = s1.Where(s => s.Age > 0); var s3 = s2.Select(s => s).FirstOrDefault();

用sql監視器查看,發現總共就執行了一次sql查詢

得出結論:

1.實現EF延遲加載 的 實際上是IQueryable上的擴展方法,更具體的話是DbQuery類型來實現的 2.IEnumerable<T>將命令直接執行,第一次執行后的結果,保存到內存,不會拼接命令樹 3.IQueryable<T>將語句拼接成一個命令樹,當用到的時候,再執行 4.兩種操作都只訪問了一次數據庫

4.為什么要有延遲加載

a.無法確定 本次查詢條件 是否 已經添加結束

DbQuery<Student> s1 = dbContext.Students.Where(s => s.Id == 1).Where(s => s.Age > 0) as DbQuery<Student>;

每次添加 查詢條件的時候,都只是返回 包含所有添加條件的 DbQuery對象,只有最后使用的時候,才根據條件生成相應的sql語句

b.對于外鍵實體,按需加載

本次需要用到的兩張 具有 主外鍵關系的兩張表如下

image

image

var tea = dbContext.Teachers.Where(t => t.tId == 1);//生成sql語句,如圖 代碼一Teacher teacher = tea.FirstOrDefault();//生成sql語句,如圖 代碼二string className = teacher.TeachClass.cName;

代碼一,如下圖:

SELECT TOP (1)     [Extent1].[tId] AS [tId],     [Extent1].[tName] AS [tName],     [Extent1].[tAge] AS [tAge],     [Extent1].[tClass] AS [tClass]    FROM [dbo].[Teacher] AS [Extent1]    WHERE 1 = [Extent1].[tId]

代碼二,如下圖:

exec sp_executesql N'SELECT     [Extent1].[cId] AS [cId],     [Extent1].[cName] AS [cName]    FROM [dbo].[TeachClass] AS [Extent1]    WHERE [Extent1].[cId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=1

觀察,得出結論:

1.按需加載:在第一次執行的時候,因為沒有用到外鍵屬性,所以生成sql語句的時候,不會去去查詢 TeachClass表 2.當EF需要用到外鍵屬性的時候,才會去加載 相應的表

c.按需加載的缺點:

實例代碼如下:

DbQuery<Teacher> teachers = dbContext.Teachers;StringBuilder sbTeacher=new StringBuilder(100);foreach (Teacher tea in teachers){    //每次調用 外鍵表Teachers上 的 外鍵實體時,都會去查詢數據庫    //EF有個優化,相同的外鍵實體只查一次,即TeachClass相同只查一次    sbTeacher.Append(tea.TeachClass.cName);}

生成的SQL腳本如下:

exec sp_executesql N'SELECT     [Extent1].[cId] AS [cId],     [Extent1].[cName] AS [cName]    FROM [dbo].[TeachClass] AS [Extent1]    WHERE [Extent1].[cId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=1

第二次,和第三次,因為TeachClass的值相同,則只查詢了一次

exec sp_executesql N'SELECT     [Extent1].[cId] AS [cId],     [Extent1].[cName] AS [cName]    FROM [dbo].[TeachClass] AS [Extent1]    WHERE [Extent1].[cId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=2

5.連接查詢

既然EF是只有用到外鍵實體的時候,才加載相應表,那么如果我們要連接兩張表要怎么做

a.通過Include方法

DbQuery<Teacher> teachers = dbContext.Teachers.Include("TeachClass");StringBuilder sbTeacher=new StringBuilder(100);foreach (Teacher tea in teachers){    //只有第一次 查詢的使用,將數據查詢 并保存到內存中,    //接下來的操作只是在內存中讀取,并沒有讀取數據庫    sbTeacher.Append(tea.TeachClass.cName);}

查看sql語句,發現 EF為我們生成 left outer  join ,連接了兩張表

SELECT     [Extent1].[tId] AS [tId],     [Extent1].[tName] AS [tName],     [Extent1].[tAge] AS [tAge],     [Extent1].[tClass] AS [tClass],     [Extent2].[cId] AS [cId],     [Extent2].[cName] AS [cName]    FROM  [dbo].[Teacher] AS [Extent1]    LEFT OUTER JOIN [dbo].[TeachClass] AS [Extent2] ON [Extent1].[tClass] = [Extent2].[cId]

b.生成 join 的另一種方式

var teachers = dbContext.Teachers.Select(t => new {tName = t.tName, ClassName = t.TeachClass.cName}).ToList();

生成的sql語句如下

SELECT     1 AS [C1],     [Extent1].[tName] AS [tName],     [Extent2].[cName] AS [cName]    FROM  [dbo].[Teacher] AS [Extent1]    LEFT OUTER JOIN [dbo].[TeachClass] AS [Extent2] ON [Extent1].[tClass] = [Extent2].[cId]

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产美女扒开尿口久久久| 久久久久免费精品国产| 国产精品尤物福利片在线观看| 日韩av高清不卡| 在线精品国产成人综合| 亚洲欧美中文另类| 亚洲在线观看视频网站| 尤物yw午夜国产精品视频| 亚洲精品视频在线观看视频| 亚洲欧美日韩国产中文| 久久久亚洲福利精品午夜| 亚洲理论在线a中文字幕| 欧美性猛交xxxx偷拍洗澡| 高潮白浆女日韩av免费看| 成人a在线观看| 欧美激情视频在线观看| 欧美丝袜第一区| 久久久久久久久亚洲| 亚洲一区精品电影| 中文字幕国产日韩| 欧美极品美女电影一区| 国产成人综合一区二区三区| 亚洲精品美女视频| 91在线视频成人| 日本a级片电影一区二区| 91高清视频免费| 国产精彩精品视频| 亚洲成人激情视频| 欧美国产日韩一区二区三区| 日韩精品在线免费观看视频| 91精品国产成人| 日韩欧美国产中文字幕| 欧美激情亚洲综合一区| 国产欧美日韩丝袜精品一区| 日韩一区二区在线视频| 国产精品视频26uuu| 欧美午夜视频一区二区| 亚洲伊人久久大香线蕉av| 中文字幕综合一区| 国产亚洲一级高清| 亚洲成人亚洲激情| 亚洲色图激情小说| 北条麻妃99精品青青久久| 欧美日韩亚洲精品一区二区三区| 91中文在线观看| 国产亚洲欧洲黄色| 在线亚洲午夜片av大片| 国产日韩欧美电影在线观看| 亚洲国产成人久久| 国产精品免费视频久久久| 亚洲欧洲黄色网| 久久九九热免费视频| 国产精品男人爽免费视频1| 日韩中文字幕在线| 日韩经典第一页| 午夜精品一区二区三区av| 综合网日日天干夜夜久久| 高清亚洲成在人网站天堂| 日韩av在线影院| 国产一区二区在线免费视频| 成人av电影天堂| 久久影视电视剧免费网站清宫辞电视| 日韩欧美精品在线观看| 亚洲男人天堂手机在线| 中文字幕最新精品| 日本在线观看天堂男亚洲| 亚洲欧美综合精品久久成人| 欧美性猛xxx| 亚洲欧美制服综合另类| 91丨九色丨国产在线| 国产精品直播网红| 亚洲国产精品久久久久久| 亚洲韩国青草视频| 日韩在线精品视频| 麻豆国产精品va在线观看不卡| 亚洲欧美综合精品久久成人| 欧美日韩成人网| 日韩av网站大全| 国产ts人妖一区二区三区| 日本久久中文字幕| 亚洲第一区第二区| 亚洲美女视频网站| 欧美成人午夜影院| 国产综合在线观看视频| 精品呦交小u女在线| 一区二区三区动漫| 亚洲xxx视频| 欧美性高潮床叫视频| 欧美午夜xxx| 亚洲视频欧洲视频| 亚洲韩国青草视频| 亚洲综合小说区| 亚洲天堂成人在线| 人体精品一二三区| 日本欧美精品在线| 日韩欧美第一页| 成人在线视频网| 97视频在线看| 日韩精品www| 欧美激情视频在线免费观看 欧美视频免费一| 不卡在线观看电视剧完整版| 国外成人在线视频| 国产精欧美一区二区三区| 亚洲欧美视频在线| 日韩在线视频观看正片免费网站| 韩剧1988免费观看全集| 欧美午夜性色大片在线观看| 欧美在线精品免播放器视频| 久久久国产在线视频| 亚洲高清不卡av| 秋霞av国产精品一区| 日韩欧美国产激情| 福利一区视频在线观看| 久久亚洲春色中文字幕| www.99久久热国产日韩欧美.com| 欧美插天视频在线播放| 日韩h在线观看| 久久夜色精品国产| 欧美性猛交xxx| 国产啪精品视频| 亚洲欧洲在线视频| 欧美人在线视频| 97精品国产91久久久久久| 国产精品v日韩精品| 国产精品久久在线观看| 2019亚洲男人天堂| 国产成人+综合亚洲+天堂| 亚洲精品日韩在线| 中文字幕一精品亚洲无线一区| 欧美黑人一区二区三区| 亚洲人成网站免费播放| 国产精品夜间视频香蕉| 亚洲精品av在线播放| 亚洲成人999| 国产91精品久久久久| 精品久久久久久国产| 黄色成人在线免费| 欧美大秀在线观看| 亚洲精品久久久一区二区三区| 色中色综合影院手机版在线观看| 亚洲色图五月天| 中文字幕久久久av一区| 亚洲天堂av在线免费观看| 国产在线a不卡| 欧美在线www| 狠狠躁18三区二区一区| 亚洲男人第一av网站| 日韩69视频在线观看| 欧美激情亚洲激情| 欧美精品一本久久男人的天堂| 日韩国产高清污视频在线观看| 国内精品在线一区| 欧美精品日韩www.p站| 久久精品国产清自在天天线| 国产a∨精品一区二区三区不卡| 欧美亚洲国产视频| 欧美精品videos另类日本| 欧美怡春院一区二区三区| 亚洲精品国产精品久久清纯直播| 91av在线不卡| 欧美日韩国产中文字幕| 欧洲成人在线观看| 88国产精品欧美一区二区三区| 精品自拍视频在线观看|