03 EF Core筆記之查詢資料

2022-01-13 13:01:49 字數 4670 閱讀 1047

ef core使用linq進行資料查詢。

我們可以通過下面的**進行簡單的查詢:

//獲取全部資料

var blogs = context.blogs.tolist();

//獲取單個實體

var blog = context.blogs.single(b => b.blogid == 1);

//篩選

var blogs = context.blogs

.where(b => b.url.contains("dotnet"))

.tolist();

ef core有三種常見模型來載入關聯資料:

使用include方法指定要包含在查詢結果中的關聯資料。例如:

using (var context = new bloggingcontext())

關聯資料可以是有層級的,可通過鏈式呼叫theninclude,進一步包含更深級別的關聯資料。:

using (var context = new bloggingcontext())

如果更改查詢,從而使其不再返回查詢以之為開頭的實體型別的例項,則會忽略 include 運算子。例如:

using (var context = new bloggingcontext())

) .tolist();

}

此時ef core會忽略包含,並生成警告日誌。

通過 dbcontext.entry(...) api 顯式載入導航屬性。例如:

using (var context = new bloggingcontext())

使用延遲載入的最簡單方式是通過安裝 microsoft.entityframeworkcore.proxies 包,並通過呼叫 uselazyloadingproxies 來啟用該包。 例如:

protected override void onconfiguring(dbcontextoptionsbuilder optionsbuilder)

=> optionsbuilder

.uselazyloadingproxies()

.usesqlserver(myconnectionstring);

或者在serviceconfigure中,呼叫services.adddbcontext方法時啟用:

services.adddbcontext(

b => b.uselazyloadingproxies()

.usesqlserver(myconnectionstring));

ef core 延遲載入需要屬性必須具有是共有的,且具有virtual修飾符,只有這樣才可以被子類重寫。為何要這樣做,可以參考我之前的文章《castle dynamicproxy基本用法(aop)》。

下面的**演示了延遲載入的用法:

public class blog

public string name

public virtual icollectionposts

}public class post

public string title

public string content

public virtual blog blog

}

此時ef core會使用**類進行延遲載入資料。

ef core還提供了不使用**的方式進行延遲載入,此方法需要向實體類中注入ilazyloader例項,並通過該例項實現get訪問:

public class blog

private blog(ilazyloader lazyloader)

private ilazyloader lazyloader

public int id

public string name

public icollectionposts

}

此種方法需要注入ilazyloader,從而造成更多的包依賴。

使用ef core延遲載入,可能會造成迴圈引用,此時無法使用json.net進行序列化,需要對此進行一些配置:

public void configureservices(iservicecollection services)

ef core支援部分查詢在客戶端進行、部分查詢傳送到伺服器,此種情況下可能會造成效能問題。

當發生客戶端篩選資料的時候,ef core會發出警告,也可以配置當發生客戶端篩選時丟擲異常:

protected override void onconfiguring(dbcontextoptionsbuilder optionsbuilder)

預設情況下,ef core跟蹤查詢返回的實體,如果我們不需要跟蹤查詢返回的實體,則可以通過asnotracking方法禁用跟蹤。

using (var context = new bloggingcontext())

或者在dbcontext級別禁用跟蹤:

using (var context = new bloggingcontext())

當使用投影查詢結果時,如果包含實體型別,則會對實體型別執行跟蹤,例如下面的查詢,將會對blog和post進行跟蹤:

using (var context = new bloggingcontext())

);}

另外,如果查詢結果中不包含任何實體型別,則不執行跟蹤。例如:

using (var context = new bloggingcontext())

);}

當linq無法滿足查詢需求,或因為使用linq生成效率比較低的sql查詢時,可以考慮使用原始sql進行查詢。ef core支援原始sql語句和儲存過程。

原始sql語句:

var blogs = context.blogs

.fromsql("select * from dbo.blogs")

.tolist();

儲存過程:

var blogs = context.blogs

.fromsql("execute dbo.getmostpopularblogs")

.tolist();

當使用原始sql進行查詢時,必須使用引數化查詢以抵禦sql注入攻擊。

好的一點是,ef core在設計時就替我們考慮了如何防禦sql注入攻擊,因此當我們使用fromsql方法時,引數中如果有使用到拼接字串的情況,則會自動為我們生成sql查詢引數,例如:

var user = "johndoe";

var blogs = context.blogs

.fromsql($"execute dbo.getmostpopularblogsforuser ")

.tolist();

上面的sql語句雖然看上去像是直接拼接的字串,其實ef core已經為我們生成了查詢引數。

當然了,我們也可以手工建立查詢引數:

var user = new sqlparameter("user", "johndoe");

var blogs = context.blogs

.fromsql("execute dbo.getmostpopularblogsforuser @user", user)

.tolist();

當資料庫的儲存過程使用了命名引數時,手工建立查詢引數將會派上用場:

var user = new sqlparameter("user", "johndoe");

var blogs = context.blogs

.fromsql("execute dbo.getmostpopularblogs @filterbyuser=@user", user)

.tolist();

當我們使用原始sql查詢時,ef core仍然支援我們使用linq編寫查詢語句。在執行查詢時,ef core會檢查我們的sql語句是否支援拼接,如果支援的情況下,則會將linq過濾語句拼接為sql一併發送到資料庫進行查詢。

原始sql中的跟蹤與linq查詢的跟蹤方式一致。

原始sql中查詢關聯資料的方式與linq查詢的關聯方式一致。

全域性篩選器對於軟刪除和多租戶非常有用。定義方式如下:

protected override void onmodelcreating(modelbuilder modelbuilder)

我們可以在特定的查詢中禁用全域性篩選器:

blogs = db.blogs

.include(b => b.posts)

.ignorequeryfilters()

.tolist();

SQL筆記03 查詢資料

第二種 第三種 not優先順序最高,其次是and和or 可以改變優先順序 in select from students where score in 90,91 the in operator is a shorthand for multiple or conditions.between th...

EFCORE筆記 全域性查詢篩選器

全域性查詢篩選器 全域性查詢篩選器用於全域性設定篩選資料的條件。常見的應用場景有 軟刪除,多租戶,禁用,啟用,多使用者部落格系統。全域性查詢篩選器可以精簡 可以提高 質量 防止開發者忘記加條件。public class blog public string name public string ur...

EFCore正確姿勢之使用where查詢

好了,直接進入正題,我們在使用ef efcore時,iqueryable where tsource this iqueryable source,expressionbool predicate where的靈活性和不可避開性,我們不得不深入 它和尊重它的存在。我們都喜歡使用where來做自己通用...