EF Core 2.1 的新功能
除了許多錯誤修正和小型的功能和效能增強功能之外,EF Core 2.1 還包含一些令人信服的新功能:
延遲載入
EF Core 現在包含必要的基礎組塊,使任何人能撰寫能根據需求載入其導覽屬性的實體類別。 我們也建立了一個新的套件,Microsoft.EntityFrameworkCore.Proxies,利用這些建構模組根據僅做最小修改的實體類別來產生惰性載入代理類別(例如,具有虛擬導覽屬性的類別)。
如需本主題的詳細資訊,請參閱有關延遲載入 的
實體建構函式中的參數
作為實作延遲載入所需的建構組塊之一,我們已啟用能夠在建構函式中接受參數的實體的建立。 您可以使用參數來插入屬性值、延遲載入委派和服務。
如需本主題的詳細資訊,請參閱使用參數 實體建構函式的
值轉換
到目前為止,EF Core 只能對應基礎資料庫提供者原生支援之類型的屬性。 在欄與屬性之間來回複製值,但沒有進行任何轉換。 從 EF Core 2.1 開始,可以使用值轉換來將從資料欄取得的值進行轉換,然後再應用於屬性上,反之亦然。 我們有許多轉換可以根據需要和慣例來應用,還有一個明確的組態 API,允許在欄位和屬性之間註冊自定義轉換。 這項功能的一些應用程式如下:
- 將列舉儲存為字串
- 使用 SQL Server 對應不帶正負號的整數
- 屬性值的自動加密和解密
如需本主題的詳細資訊,請參閱有關值轉換 的
LINQ GroupBy 翻譯
在 2.1 版之前,在 EF Core 中,GroupBy LINQ 運算符一律會在記憶體中評估。 我們現在支援在最常見的案例中將它轉譯為 SQL GROUP BY 子句。
此範例示範使用 GroupBy 來計算各種聚合函數的查詢:
var query = context.Orders
.GroupBy(o => new { o.CustomerId, o.EmployeeId })
.Select(g => new
{
g.Key.CustomerId,
g.Key.EmployeeId,
Sum = g.Sum(o => o.Amount),
Min = g.Min(o => o.Amount),
Max = g.Max(o => o.Amount),
Avg = g.Average(o => o.Amount)
});
對應的 SQL 轉譯如下所示:
SELECT [o].[CustomerId], [o].[EmployeeId],
SUM([o].[Amount]), MIN([o].[Amount]), MAX([o].[Amount]), AVG([o].[Amount])
FROM [Orders] AS [o]
GROUP BY [o].[CustomerId], [o].[EmployeeId];
數據植入
有了新版本,就可以提供初始數據來填入資料庫。 不同於 EF6,植入數據會與實體類型相關聯,做為模型組態的一部分。 然後 EF Core 移轉可以自動計算將資料庫升級至新版本模型時,需要套用哪些插入、更新或刪除作業。
例如,您可以使用此項目在 OnModelCreating
中設定 Post 的種子資料:
modelBuilder.Entity<Post>().HasData(new Post{ Id = 1, Text = "Hello World!" });
如需本主題的詳細資訊,請參閱有關數據植入 的
查詢類型
EF Core 模型現在可以包含查詢類型。 與實體類型不同的是,查詢類型上沒有定義索引鍵,而且無法插入、刪除或更新(也就是說,它們是唯讀的),但是查詢可以直接傳回這些索引鍵。 查詢類型的一些使用案例如下:
- 對應至沒有主鍵的檢視
- 將映射至不含主鍵的資料表
- 對應至模型中定義的查詢
- 做為
FromSql()
查詢的傳回型別
如需本主題的詳細資訊,請參閱查詢類型
包含衍生型別
現在在撰寫 Include
方法的表達式時,可以僅指定定義在衍生型別上的導覽屬性。 針對強型別版本的 Include
,我們支援使用明確轉換或 as
運算符。 我們現在也支援在 Include
字串版本中,使用衍生類型上所定義的導覽屬性名稱進行參考:
var option1 = context.People.Include(p => ((Student)p).School);
var option2 = context.People.Include(p => (p as Student).School);
var option3 = context.People.Include("School");
如需本主題的詳細資訊,請閱讀 一節中關於 包含衍生類型的內容。
System.Transactions 的支援
我們已新增使用 System.Transactions 功能的功能,例如 TransactionScope。 使用支援 .NET Framework 的資料庫提供者時,這適用於 .NET Framework 和 .NET Core。
如需本主題的詳細資訊,請參閱 System.Transactions 上的
在初始遷移中更佳的欄位順序
根據客戶的反饋,我們已更新遷移,以便首先按照類別中屬性的宣告順序,產生資料表的欄位。 請注意,在初始數據表建立之後加入新成員時,EF Core 無法變更順序。
相互關聯的子查詢優化
我們已改善查詢翻譯,以避免在許多常見情境中執行「N + 1」的 SQL 查詢,這些情境中,投影中使用導覽屬性會導致從根查詢與相互關聯的子查詢數據聯結。 優化過程需要暫存子查詢的結果,我們要求您修改查詢來啟用這一新行為。
例如,下列查詢通常會轉譯成客戶的一個查詢,加上 N (其中 “N” 是傳回的客戶數目)個別的訂單查詢:
var query = context.Customers.Select(
c => c.Orders.Where(o => o.Amount > 100).Select(o => o.Amount));
藉由在正確的位置包含 ToListAsync()
,您表明緩衝適用於訂單,從而啟用優化功能。
var query = context.Customers.Select(
c => c.Orders.Where(o => o.Amount > 100).Select(o => o.Amount).ToList());
請注意,此查詢只會轉譯為兩個 SQL 查詢:一個用於客戶,另一個用於訂單。
[已擁有] 屬性
現在,只要對類型使用 [Owned]
標註,並確保將擁有者實體添加到模型中,即可配置 擁有的實體類型。
[Owned]
public class StreetAddress
{
public string Street { get; set; }
public string City { get; set; }
}
public class Order
{
public int Id { get; set; }
public StreetAddress ShippingAddress { get; set; }
}
.NET Core SDK 中包含的命令行工具 dotnet-ef
dotnet-ef 命令現在是 .NET Core SDK 的一部分,因此不再需要在專案中使用 DotNetCliToolReference,才能使用移轉,或從現有的資料庫建構 DbContext。
如需如何為不同 .NET Core SDK 和 EF Core 版本啟用命令行工具的詳細資訊,請參閱 安裝工具一節。
Microsoft.EntityFrameworkCore.Abstractions 套件
新套件包含屬性和介面,您可以在專案中用來點亮 EF Core 功能,而不需完全依賴 EF Core。 例如,[Owned] 屬性和 ILazyLoader 介面位於這裡。
狀態變更事件
ChangeTracker
上的新 Tracked
和 StateChanged
事件可以用來撰寫邏輯,以應對實體進入 DbContext 或改變其狀態。
原始 SQL 參數分析器
EF Core 隨附新的程式碼分析器,可偵測原始 SQL API 可能不安全的使用方式,例如 FromSql
或 ExecuteSqlCommand
。 例如,針對下列查詢,您會看到警告,因為 minAge 未參數化:
var sql = $"SELECT * FROM People WHERE Age > {minAge}";
var query = context.People.FromSql(sql);
資料庫提供者相容性
建議您使用已更新或至少已測試能與 EF Core 2.1 一同運作的提供者來使用 EF Core 2.1。
提示
如果您在新功能中發現任何非預期的不相容或任何問題,或您對這些功能有意見反應,請使用 我們的問題追蹤程序回報。