EF Core 2.1 中的新功能New features in EF Core 2.1

注意

這個版本仍處於預覽狀態。This release is still in preview.

除了許多 Bug 修正和小型的功能和效能增強之外,EF Core 2.1 還包含一些吸引人的新功能:Besides numerous bug fixes and small functional and performance enhancements, EF Core 2.1 includes some compelling new features:

消極式載入Lazy loading

EF Core 現在包含必要的建置組塊,可讓任何人撰寫實體類別,以視需要載入其導覽屬性。EF Core now contains the necessary building blocks for anyone to author entity classes that can load their navigation properties on demand. 我們也已建立新套件 Microsoft.EntityFrameworkCore.Proxies,該套件利用這些建置組塊來產生以最小修改之實體類別為基礎的消極式載入 Proxy 類別 (例如具有虛擬導覽屬性的類別)。We have also created a new package, Microsoft.EntityFrameworkCore.Proxies, that leverages those building blocks to produce lazy loading proxy classes based on minimally modified entity classes (e.g. classes with virtual navigation properties).

如需此主題的詳細資訊,請閱讀消極式載入一節。Read the section on lazy loading for more information about this topic.

實體建構函式中的參數Parameters in entity constructors

因為是消極式載入所需要建置組塊之一,所以我們允許建立實體,由其建構函式來接受參數。As one of the required building blocks for lazy loading, we enabled the creation of entities that take parameters in their constructors. 您可以使用這些參數來插入屬性值、消極式載入委派和服務。You can use parameters to inject property values, lazy loading delegates, and services.

如需此主題的詳細資訊,請閱讀含參數的實體建構函式一節。Read the section on entity constructor with parameters for more information about this topic.

值轉換Value conversions

到目前為止,EF Core 只能對應基礎資料庫提供者原生支援類型的屬性。Until now, EF Core could only map properties of types natively supported by the underlying database provider. 這些值會在資料行與屬性之間來回複製,無須進行任何轉換。Values were copied back and forth between columns and properties without any transformation. 從 EF Core 2.1 開始,您可以套用值轉換來轉換從資料行取得的值,再將這些值套用至屬性,反之亦然。Starting with EF Core 2.1, value conversions can be applied to transform the values obtained from columns before they are applied to properties, and vice versa. 我們有一些可以依照慣例視需要套用的轉換,以及允許在資料行與屬性之間註冊自訂轉換的明確組態 API。We have a number of conversions that can be applied by convention as necessary, as well as an explicit configuration API that allows registering custom conversions between columns and properties. 這項功能的一些應用包括:Some of the application of this feature are:

  • 將列舉儲存為字串Storing enums as strings
  • 使用 SQL Server 對應不帶正負號的整數Mapping unsigned integers with SQL Server
  • 屬性值的自動加密和解密Automatic encryption and decryption of property values

如需此主題的詳細資訊,請閱讀值轉換一節。Read the section on value conversions for more information about this topic.

LINQ GroupBy 轉譯LINQ GroupBy translation

在 2.1 版之前,EF Core 中的 GroupBy LINQ 運算子永遠會在記憶體內部評估。Before version 2.1, in EF Core the GroupBy LINQ operator was always be evaluated in memory. 我們現在支援在最常見的案例中將它轉譯成 SQL GROUP BY 子句。We now support translating it to the SQL GROUP BY clause in most common cases.

此範例會顯示使用 GroupBy 來計算各種彙總函式的查詢:This example shows a query with GroupBy used to compute various aggregate functions:

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 => Amount)
        });

對應的 SQL 轉譯如下所示:The corresponding SQL translation looks like this:

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

資料植入Data Seeding

在此新版本中,您可以提供初始資料來填入資料庫。With the new release it will be possible to provide initial data to populate a database. 不同於 EF6,植入資料與屬於模型組態一部分的實體類型相關聯。Unlike in EF6, seeding data is associated to an entity type as part of the model configuration. 然後,將資料庫升級至新版模型時,EF Core 移轉可以自動計算需要套用的插入、更新或刪除作業。Then EF Core migrations can automatically compute what insert, update or delete operations need to be applied when upgrading the database to a new version of the model.

例如,您可以使用此選項,為 OnModelCreating 中的 Post 設定種子資料:As an example, you can use this to configure seed data for a Post in OnModelCreating:

modelBuilder.Entity<Post>().HasData(new Post{ Id = 1, Text = "Hello World!" });

如需此主題的詳細資訊,請閱讀資料植入一節。Read the section on data seeding for more information about this topic.

查詢類型Query types

EF Core 模型現在可以包含查詢類型。An EF Core model can now include query types. 不同於實體類型,查詢類型並未定義索引鍵,而且無法插入、刪除或更新 (亦即這些類型是唯讀的),但可以直接由查詢傳回。Unlike entity types, query types do not have keys defined on them and cannot be inserted, deleted or updated (i.e. they are read-only), but they can be returned directly by queries. 查詢類型的一些使用方式情節包括:Some of the usage scenarios for query types are:

  • 對應至不含主索引鍵的檢視表Mapping to views without primary keys
  • 對應至不含主索引鍵的資料表Mapping to tables without primary keys
  • 對應至模型中已定義的查詢Mapping to queries defined in the model
  • 作為 FromSql() 查詢的傳回型別Serving as the return type for FromSql() queries

如需此主題的詳細資訊,請閱讀查詢類型一節。Read the section on query types for more information about this topic.

隨附於衍生類型Include for derived types

現在,當您為 Include 方法撰寫運算式時,您可以指定只在衍生類型上定義的導覽屬性。It will be now possible to specify navigation properties only defined on derived types when writing expressions for the Include method. 針對 Include 的強型別版本,我們支援使用明確轉換或 as 運算子。For the strongly typed version of Include, we support using either an explicit cast or the as operator. 我們現在也支援參考 Include 的字串版本中衍生類型上所定義的導覽屬性名稱:We also now support referencing the names of navigation property defined on derived types in the string version of 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");

如需此主題的詳細資訊,請閱讀隨附於衍生類型一節。Read the section on Include with derived types for more information about this topic.

System.Transactions 支援System.Transactions support

我們新增了使用 System.Transactions 功能的能力,例如 TransactionScope。We have added the ability to work with System.Transactions features such as TransactionScope. 使用支援的資料庫提供者時,這會適用於 .NET Framework 和 .NET Core。This will work on both .NET Framework and .NET Core when using database providers that support it.

如需此主題的詳細資訊,請閱讀 System.Transactions 一節。Read the section on System.Transactions for more information about this topic.

改進初始移轉中的資料行排序Better column ordering in initial migration

根據客戶的意見反應,我們已更新移轉,一開始就依類別中宣告屬性的相同順序來產生資料表的資料行。Based on customer feedback, we have updated migrations to initially generate columns for tables in the same order as properties are declared in classes. 請注意,若在初始資料表建立之後新增成員,EF Core 就無法變更順序。Note that EF Core cannot change order when new members are added after the initial table creation.

相互關聯子查詢的最佳化Optimization of correlated subqueries

我們已改善查詢轉譯,避免在許多常見情節中執行 "N + 1" SQL 查詢,在這些情節中,於投影中使用導覽屬性會導致根查詢中的資料與相互關聯子查詢中的資料相聯結。We have improved our query translation to avoid executing "N + 1" SQL queries in many common scenarios in which the usage of a navigation property in the projection leads to joining data from the root query with data from a correlated subquery. 最佳化需要緩衝處理形成子查詢的結果,而且我們需要您修改查詢以加入新的行為。The optimization requires buffering the results form the subquery, and we require that you modify the query to opt-in the new behavior.

例如,下列查詢通常會轉譯成一個用於客戶的查詢,再加上 N (其中 "N" 是傳回的客戶數目) 個用於訂單的個別查詢:As an example, the following query normally gets translated into one query for Customers, plus N (where "N" is the number of customers returned) separate queries for Orders:

var query = context.Customers.Select(
    c => c.Orders.Where(o => o.Amount  > 100).Select(o => o.Amount));

藉由在正確位置包含 ToList(),您可以指出緩衝處理適用於訂單,因此可啟用最佳化:By including ToList() in the right place, you indicate that buffering is appropriate for the Orders, which enable the optimization:

var query = context.Customers.Select(
    c => c.Orders.Where(o => o.Amount  > 100).Select(o => o.Amount).ToList());

請注意這項查詢只會轉譯成兩個 SQL 查詢:一個用於客戶,另一個用於訂單。Note that this query will be translated to only two SQL queries: One for Customers and the next one for Orders.

OwnedAttributeOwnedAttribute

您現在可以直接對類型標註 [Owned],然後確定擁有者實體已新增至模型,來設定擁有的實體類型It is now possible to configure owned entity types by simply annotating the type with [Owned] and then making sure the owner entity is added to the model:

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

新的 dotnet-ef 通用工具New dotnet-ef global tool

dotnet-ef 命令已轉換為 .NET CLI 通用工具,因此不再需要在專案中使用 DotNetCliToolReference 才能使用移轉,或從現有的資料庫建立 DbContext 結構。The dotnet-ef commands have been converted to a .NET CLI global tool, so it will no longer be necessary to use DotNetCliToolReference in the project to be able to use migrations or to scaffold a DbContext from an existing database.

Microsoft.EntityFrameworkCore.Abstractions 套件Microsoft.EntityFrameworkCore.Abstractions package

新的套件包含屬性和介面,您可以在專案中使用這些屬性和介面來啟用 EF Core 功能,而不必仰賴整體 EF Core。The new package contains attributes and interfaces that you can use in your projects to light up EF Core features without taking a dependency on EF Core as a whole. 例如,E.g. Preview 1 中引進的 [Owned] 屬性已移到此處。the [Owned] attribute introduced in Preview 1 was moved here.

狀態變更事件State change events

ChangeTracker 上的新 TrackedStateChanged 事件可用於撰寫邏輯,該邏輯會針對進入 DbContext 或改變其狀態的實體進行回應。New Tracked And StateChanged events on ChangeTracker can be used to write logic that reacts to entities entering the DbContext or changing their state.

原始的 SQL 參數分析器Raw SQL parameter analyzer

EF Core 隨附一個新的程式碼分析工具,可偵測原始 SQL API (例如 FromSqlExecuteSqlCommand) 可能不安全的使用方式。A new code analyzer is included with EF Core that detects potentially unsafe usages of our raw-SQL APIs, like FromSql or ExecuteSqlCommand. 例如,E.g. 下列查詢中,您將看到警告,因為 minAge 未參數化:for the following query, you will see a warning because minAge is not parameterized:

var sql = $"SELECT * FROM People WHERE Age > {minAge}";
var query = context.People.FromSql(sql);

資料庫提供者相容性Database provider compatibility

EF Core 2.1 已設計成與專為 EF Core 2.0 建立的資料庫提供者相容,或至少需要極少的變更。EF Core 2.1 was designed to be compatible with database providers created for EF Core 2.0, or at least require minimal changes. 雖然上述某些功能 (例如值轉換) 需要更新的提供者,但其他功能 (例如消極式載入) 則受到現有提供者的支援。While some of the features described above (e.g. value conversions) require an updated provider, others (e.g. lazy loading) will light up with existing providers.

提示

如果您在新功能中發現未預期的不相容或任何問題,或者如果您有相關意見反應,請使用我們的問題追蹤程式進行回報。If you find any unexpected incompatibility or any issue in the new features, or if you have feedback on them, please report it using our issue tracker.