前言
目前 EF Core 的最新版本為 2.0.0-priview1-final
,所以本篇文章主要是針對此版本的一些說明。
注意:如果你要在Visual Studio 中使用 .NET Core 2.0 , 你需要至少 Visual Studio 2017 15.3 預覽版本。
安裝或升級到 EF Core 2.0
你可以通過以下命令來安裝或者升級你目前的 .NET Core 版本。
// 安裝PM> install-package Microsoft.EntityFrameworkCore.SqlServer -Pre -Version 2.0.0-preview1-final// 升級PM> update-package Microsoft.EntityFrameworkCore.SqlServer -Pre -Version 2.0.0-preview1-final
工具包
// 直接修改 CSPROJ 檔案<ItemGroup> <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0-preview1-final" /></ItemGroup>// 或者通過以下命令PM> update-package Microsoft.EntityFrameworkCore.Tools -Pre -Version 2.0.0-preview1-final
EF Core 2.0 新功能
改進的 LINQ 翻譯
EF.Functions.Like()
在 EF Core 2.0 中添加了 EF.Functions 屬性,EF Core Provider 可以使用它們來自訂一些映射到資料庫函數後者運算子的方法,以便於在 LINQ 查詢中調用它們。如:
var aCustomers = from c in context.Customers where EF.Functions.Like(c.Name, "a%"); select c;
分離實體和表
分離實體和表什麼意思呢?在以前,一個資料庫表會映射到 EF 中的一個實體物件,也就是表和實體是一一對應的關係。那麼在 2.0 版本中,允許映射一些關聯的實體到一個表中,並且EF會維護這些執行個體或者參考關聯性。
modelBuilder.Entity<Customer>() .OwnsOne(c => c.WorkAddress);public class Customer{ public int CustomerId { get; set; } public Address WorkAddress { get; set; }}public class Address{ public string Line { get; set; } public string PostalOrZipCode { get; set; } public string StateOrProvince { get; set; } public string CityOrTown { get; internal set; }}
在產生資料庫表的時候,Customer
和 Address
將產生為一個表。
注意:priview1 中此功能暫不完整。
全域查詢過濾
新版本引入了一個叫做“垂直過濾”的一個功能,這是一個比較常見的需求。
在我們定義EF Core上下文模型的時候,可以在模型建立的時候附加一些過濾條件,比如在查詢的時候總是過濾掉一些“邏輯刪除”的資料。
public class BloggingContext : DbContext{ public DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } public int TenantId {get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Post>() .HasQueryFilter(p => !p.IsDeleted && p.TenantId == this.TenantId ); }}
當通過直接查詢或者導覽屬性(Include()
)查詢類型資料時,將會自動應用此過濾條件。當然你可以使用 IgnoreQueryFilters()
來在查詢中禁用此全域過濾器。
DbContext 串連池
通常在 ASP.NET Core 中使用 EF Core 會涉及到自訂的 DbContext,然後注入到系統容器中,再通過 Controller 的建構函式從容器中來擷取該對象執行個體。這也就意味著在每個請求中都會建立一個新的執行個體。
在EF Core 2.0 中,引入了一種新的注入自訂DbContext的方式,它顯示的使用了一種執行個體池的方式來注入到容器。
services.AddDbContextPool<BloggingContext>( options => options.UseSqlServer(connectionString));
使用此方式的話,當 Controller 請求 DbContext 執行個體的時候,將會首先檢查池中是否有可用的執行個體,一旦請求處理完成,附加到改執行個體上的任何狀態都將會重設,然後執行個體會重新返回到池中。
這個概念有點類似 ADO.NET 中的資料庫連接池,它具有節省初始化 DbContext 執行個體成本的優點。很多ASP.NET Core 應用程式可以採用此方式來獲得效能上的提升。
手動編譯查詢
在以前版本的 EF 和 Linq to SQL 中提供有可以手動或者顯示的編譯查詢的API,它允許應用程式緩衝已經翻譯的查詢,這樣他們就可以只編譯一次,並且執行多次。
雖然 EF Core 可以根據查詢運算式自動編譯和緩衝查詢,但是這種機制可以通過繞過雜湊計算或者快取來擷取小幅的查詢效能提升,從而允許應用程式使用已經調用委託鏈編譯通過的查詢。
private static Func<CustomerContext, int, Customer> _customerById = EF.CompileQuery((CustomerContext db, int id) => db.Customers .Include(c => c.Address) .Single(c => c.Id == id));...using (var db = new CustomerContext()){ var customer = _customerById(db, 147);}
其他
EF Core 2.0 還將對一些日誌記錄以及診斷的基礎架構進行一些比較大的調整,以及和 Azure Application Insights 的整合工作。
對於 Lazy Loading (消極式載入)功能的增加,目前還在討論當中,也許會在 EF Core 2.1 中添加此功能。