[英]Net Core: Find Primary Key of Entity Framework Core and Reflection
[英]Net Core: Generic Repository Primary Id Key Performance in Entity Framework
我們正在審查通用存儲庫模式中的兩種不同方法。 目前,想要將主鍵映射到 Id。 這樣做的目的是映射到使用 Id 的通用存儲庫接口。 下面提供兩種解決方案。
.FindPrimaryKey().Properties 對性能有何影響。 在嘗試查找主鍵時,它是否會導致數據庫表上的模式鎖定? 它會導致任何應用程序緩慢嗎?
它與部分類方法解決方案 2 的性能相比如何? 什么選擇在性能方面更好?
注意:架構師要求在工作場所使用存儲庫模式,因此實施它。 知道圍繞這個問題有爭論,但不是我的呼吁。
腳手架模型示例:
namespace Datatest
{
public partial class Property
{
public int Property { get; set; }
public int DocumentId { get; set; }
public string Address { get; set; }
}
}
所有表的示例通用基礎存儲庫:
public T Get(int id)
{
return Table.Find(id);
}
public async Task<T> GetAsync(int id)
{
return await Table.FindAsync(id);
}
public T Single(Expression<Func<T, bool>> predicate)
{
return All.Single(predicate);
}
public async Task<T> SingleAsync(Expression<Func<T, bool>> predicate)
{
return await All.SingleAsync(predicate);
}
public T FirstOrDefault(int id)
{
return All.FirstOrDefault(CreateEqualityExpressionForId(id));
}
解決方案 1:FindPrimaryKey()
使用 EF FindPrimaryKey()
var idName = _context.Model.FindEntityType(typeof(TEntity))
.FindPrimaryKey().Properties.Single().Name;
解決方案2:部分類映射
Net Core:為所有表創建通用存儲庫接口 ID 映射自動代碼生成
public partial class Property: IEntity
{
[NotMapped]
public int Id { get => PropertyId; set => PropertyId = value; }
}
關於第一種方法(使用 EF Core 元數據服務):
首先,EF Core 是 ORM(對象關系映射器),這里最重要的是Mapper 。
其次,它使用所謂的基於代碼的模型,這意味着所有映射都是由代碼提供的,而不是由實際數據庫提供的(即使模型是通過對現有數據庫進行逆向工程創建的)。
簡而言之,EF Core 在運行時創建一個內存數據結構,其中包含有關類和屬性的信息(元數據)以及它們到數據庫表、列和關系的映射。 所有這些信息都基於純代碼模型——實體類、約定、數據注釋和流暢的配置。
所有 EF Core 運行時行為都基於該元數據模型。 EF Core 在構建查詢、將查詢結果映射到對象、鏈接導航屬性、生成創建/更新/刪除命令及其執行順序、在獲取真正的自動生成的主要鍵值后更新臨時 FK 屬性值等時在內部使用它。
因此,元數據模型和發現服務(方法)使用優化的數據結構並且(必須)非常高效。 同樣,不涉及數據庫操作。
所以第一種方法非常有效。 與實際的查詢構建、執行和具體化相比,通過元數據服務獲取 PK屬性名稱的性能影響可以忽略不計。
此外,第一種方法的性能類似於您在另一種方法中使用的 EF Core Find
方法。 請注意,在調用Find
方法時,您只傳遞 PK 值而不是屬性。 所以方法實現應該知道如何構建Where
表達式,對嗎? 它在內部所做的與建議的代碼段非常相似。
關於第二種方法:
它根本沒有可比性,因為它不起作用。 可以使用基類/接口,但HasColumnName
是映射了實際的屬性名稱 - 就像所有類都具有Id
屬性一樣,並且使用[Column]
數據注釋或HasColumnName
fluent API 將其映射到數據庫表中的不同列名稱。
在您的示例中, Id
屬性為[NotMapped]
(忽略)。 這意味着 EF Core 無法映射到表列。 您通過代碼(屬性 getter/setter)將其映射到另一個屬性的事實並不重要。 EF Core不是(反)編譯器,它看不到您的代碼,因此無法將使用此類屬性的 LINQ 查詢轉換為 SQL。
在 EF Core 2.x 中,這會導致 客戶端評估(效率非常低,讀取整個表並在內存中應用過濾器),或者如果客戶端評估配置為這樣做,則會導致異常。 而在 EF Core 3.0+ 中,它將始終是一個例外。
因此,如果您不刪除諸如PropertyId
類的PropertyId
並映射屬性Id
(這對於“數據庫優先”模型來說很困難),則應避免使用第二種“方法”。 即使您可以映射實際的Id
屬性,您所節省的時間也只是幾毫秒。 再說一次,在使用Find
您不必擔心性能,何必為使用相同(或相似)方法的方法而煩惱。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.