EF Core 2.0 新特性


前言

目前 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 翻譯

  • 避免創建不必要的子查詢
  • 一些命令將切換到客戶端進行執行
  • 只有少數請求才會檢索表的所有列
  • 有事沒有適當的過濾條件,將單個LINQ 查詢轉換為 N + 1 查詢。

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; }
}

在生成數據庫表的時候,CustomerAddress 將生成為一個表。

注意: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 中添加此功能。


原文地址:https://blogs.msdn.microsoft.com/dotnet/2017/05/12/announcing-ef-core-2-0-preview-1
翻譯:楊曉東(Savorboard)
本文地址:http://www.cnblogs.com/savorboard/p/announcing-ef-core-2-0.html
歡迎轉載,請在明顯位置給出出處及鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM