EF Core 3.x に含まれる破壊的変更Breaking changes included in EF Core 3.x

次の API および動作の変更により、3.x へのアップグレード時に、既存のアプリケーションが中断される可能性があります。The following API and behavior changes have the potential to break existing applications when upgrading them to 3.x. データベース プロバイダーにのみ影響することが予想される変更については、プロバイダーの変更に関するページに記載されています。Changes that we expect to only impact database providers are documented under provider changes.

まとめSummary

重大な変更Breaking change 影響Impact
LINQ クエリがクライアントで評価されなくなったLINQ queries are no longer evaluated on the client High
EF Core 3.0 では .NET Standard 2.0 ではなく .NET Standard 2.1 がターゲットにされるEF Core 3.0 targets .NET Standard 2.1 rather than .NET Standard 2.0 High
EF Core のコマンドライン ツールである dotnet ef が .NET Core SDK の一部ではなくなったThe EF Core command-line tool, dotnet ef, is no longer part of the .NET Core SDK High
DetectChanges でストア生成キーの値が優先されるDetectChanges honors store-generated key values High
FromSql、ExecuteSql、および ExecuteSqlAsync の名前変更FromSql, ExecuteSql, and ExecuteSqlAsync have been renamed High
クエリ型がエンティティ型と統合されるQuery types are consolidated with entity types High
Entity Framework Core が ASP.NET Core 共有フレームワークの一部ではなくなったEntity Framework Core is no longer part of the ASP.NET Core shared framework MediumMedium
既定で連鎖削除がすぐに行われるようになったCascade deletions now happen immediately by default MediumMedium
関連エンティティの一括読み込みが 1 つのクエリで行われるようになったEager loading of related entities now happens in a single query MediumMedium
DeleteBehavior.Restrict のセマンティクスがクリーンになりましたDeleteBehavior.Restrict has cleaner semantics MediumMedium
所有型のリレーションシップ用の構成 API が変更されたConfiguration API for owned type relationships has changed MediumMedium
各プロパティで独立したメモリ内整数キー生成が使用されるEach property uses independent in-memory integer key generation MediumMedium
追跡なしのクエリでは、識別子の解決が実行されなくなったNo-tracking queries no longer perform identity resolution MediumMedium
メタデータ API の変更点Metadata API changes MediumMedium
プロバイダー固有のメタデータ API の変更Provider-specific Metadata API changes MediumMedium
UseRowNumberForPaging の削除UseRowNumberForPaging has been removed MediumMedium
FromSql メソッドをストアド プロシージャと共に使用して構成することができないFromSql method when used with stored procedure cannot be composed MediumMedium
FromSql メソッドはクエリのルートでのみ指定できるFromSql methods can only be specified on query roots Low
クエリの実行がデバッグ レベルでログに記録される 元に戻されますQuery execution is logged at Debug level Reverted Low
一時キーの値がエンティティ インスタンスに設定されなくなったTemporary key values are no longer set onto entity instances Low
プリンシパルとテーブルを共有する依存エンティティが省略可能になりましたDependent entities sharing the table with the principal are now optional Low
同時実行トークン列とテーブルを共有するすべてのエンティティをプロパティにマップする必要があります。All entities sharing a table with a concurrency token column have to map it to a property Low
所有エンティティは、所有者がいないと、追跡クエリを使用してクエリを実行することができないOwned entities cannot be queried without the owner using a tracking query Low
マップされていない型から継承されたプロパティは、すべての派生型の 1 つの列にマップされるようになりましたInherited properties from unmapped types are now mapped to a single column for all derived types Low
外部キー プロパティの規則がプリンシパル プロパティと同じ名前と一致しなくなったThe foreign key property convention no longer matches same name as the principal property Low
データベース接続は、これ以上使用されない場合、TransactionScope が完了する前に閉じられるようになりましたDatabase connection is now closed if not used anymore before the TransactionScope has been completed Low
バッキング フィールドが既定で使用されるBacking fields are used by default Low
複数の互換性があるバッキング フィールドが見つかった場合にスローされるThrow if multiple compatible backing fields are found Low
フィールド専用プロパティの名前はフィールドの名前に一致する必要がありますField-only property names should match the field name Low
AddDbContext/AddDbContextPool で AddLogging および AddMemoryCache を呼び出さなくなりましたAddDbContext/AddDbContextPool no longer call AddLogging and AddMemoryCache Low
AddEntityFramework* により、サイズ制限がある IMemoryCache が追加されるAddEntityFramework* adds IMemoryCache with a size limit Low
DbContext.Entry でローカルの DetectChanges が実行されるようになったDbContext.Entry now performs a local DetectChanges Low
文字列とバイト配列のキーが既定でクライアントによって生成されないString and byte array keys are not client-generated by default Low
ILoggerFactory がスコープ サービスになったILoggerFactory is now a scoped service Low
遅延読み込みプロキシで、ナビゲーション プロパティが完全に読み込まれたと見なされなくなったLazy-loading proxies no longer assume navigation properties are fully loaded Low
内部サービス プロバイダーの過剰な作成が既定でエラーと見なされるようになったExcessive creation of internal service providers is now an error by default Low
1 つの文字列と共に呼び出される HasOne/HasMany の新しい動作New behavior for HasOne/HasMany called with a single string Low
いくつかの非同期メソッドの戻り値の型が Task から ValueTask に変更されましたThe return type for several async methods has been changed from Task to ValueTask Low
Relational:TypeMapping 注釈が単に TypeMapping となったThe Relational:TypeMapping annotation is now just TypeMapping Low
派生型の ToTable で例外がスローされるToTable on a derived type throws an exception Low
EF Core で SQLite FK を適用するためのプラグマが送信されなくなったEF Core no longer sends pragma for SQLite FK enforcement Low
Microsoft.EntityFrameworkCore.Sqlite が SQLitePCLRaw.bundle_e_sqlite3 に依存するようになったMicrosoft.EntityFrameworkCore.Sqlite now depends on SQLitePCLRaw.bundle_e_sqlite3 Low
GUID の値が SQLite にテキストとして格納されるようになったGuid values are now stored as TEXT on SQLite Low
Char の値が SQLite にテキストとして格納されるようになったChar values are now stored as TEXT on SQLite Low
移行 ID がインバリアント カルチャの暦を使用して生成されるようになったMigration IDs are now generated using the invariant culture's calendar Low
IDbContextOptionsExtension から拡張機能の情報/メタデータを削除Extension info/metadata has been removed from IDbContextOptionsExtension Low
LogQueryPossibleExceptionWithAggregateOperator の名前が変更されたLogQueryPossibleExceptionWithAggregateOperator has been renamed Low
外部キー制約名の API が明確化されたClarify API for foreign key constraint names Low
IRelationalDatabaseCreator.HasTables/HasTablesAsync をパブリックに変更IRelationalDatabaseCreator.HasTables/HasTablesAsync have been made public Low
Microsoft.EntityFrameworkCore.Design を DevelopmentDependency パッケージに変更Microsoft.EntityFrameworkCore.Design is now a DevelopmentDependency package Low
SQLitePCL.raw のバージョン 2.0.0 への更新SQLitePCL.raw updated to version 2.0.0 Low
NetTopologySuite のバージョン 2.0.0 への更新NetTopologySuite updated to version 2.0.0 Low
System.Data.SqlClient ではなく Microsoft.Data.SqlClient が使用されるMicrosoft.Data.SqlClient is used instead of System.Data.SqlClient Low
複数のあいまいな自己参照リレーションシップを構成する必要があるMultiple ambiguous self-referencing relationships must be configured Low
DbFunction.Schema が null または空の文字列である場合、モデルの既定のスキーマに構成されるDbFunction.Schema being null or empty string configures it to be in model's default schema Low

LINQ クエリがクライアントで評価されなくなったLINQ queries are no longer evaluated on the client

問題 #14935 の追跡 問題 #12795 も参照Tracking Issue #14935 Also see issue #12795

以前の動作Old behavior

3.0 より前では、EF Core では、SQL またはパラメーターに対するクエリの一部だった式を変換できない場合、クライアントで自動的に式が評価されていました。Before 3.0, when EF Core couldn't convert an expression that was part of a query to either SQL or a parameter, it automatically evaluated the expression on the client. 既定では、コストの高い式のクライアント評価でのみ警告がトリガーされました。By default, client evaluation of potentially expensive expressions only triggered a warning.

新しい動作New behavior

3.0 以降では、クライアントで評価される最上位のプロジェクション (クエリの最後の Select() 呼び出し) の式のみが EF Core で許可されます。Starting with 3.0, EF Core only allows expressions in the top-level projection (the last Select() call in the query) to be evaluated on the client. クエリの他の部分の式を SQL やパラメーターに変換できない場合、例外がスローされます。When expressions in any other part of the query can't be converted to either SQL or a parameter, an exception is thrown.

理由Why

クエリの自動クライアント評価では、多くのクエリを実行できます。これらの重要な部分を変換できない場合でも同様です。Automatic client evaluation of queries allows many queries to be executed even if important parts of them can't be translated. この動作が原因で、予期しない損害を与える動作となる可能性があります。この動作は、運用環境でのみ見られる場合があります。This behavior can result in unexpected and potentially damaging behavior that may only become evident in production. たとえば、変換できない Where() 呼び出しの条件が原因で、テーブルのすべての行がデータベース サーバーから転送できるようになり、クライアントでフィルターを適用できるようになる場合があります。For example, a condition in a Where() call which can't be translated can cause all rows from the table to be transferred from the database server, and the filter to be applied on the client. このような状況は、開発時にテーブルにわずかな行が含まれている場合は、簡単に検出される可能性があります。しかし、テーブルに数百万もの行が含まれる、運用環境にアプリケーションを移行する場合は難しくなる可能性があります。This situation can easily go undetected if the table contains only a few rows in development, but hit hard when the application moves to production, where the table may contain millions of rows. クライアント評価の警告では、開発中にあまりに簡単に無視されることも示されていました。Client evaluation warnings also proved too easy to ignore during development.

これだけでなく、自動クライアント評価は、特定の式のクエリ変換の改善が、リリース間の予期しない破壊的変更の原因となる問題につながる可能性があります。Besides this, automatic client evaluation can lead to issues in which improving query translation for specific expressions caused unintended breaking changes between releases.

軽減策Mitigations

クエリを完全に変換できない場合は、変換できる形式でクエリを書き直すか、AsEnumerable()ToList()、または同様のものを使用して、LINQ-to-Objects を使ってさらに処理できるクライアントに明示的にデータを戻します。If a query can't be fully translated, then either rewrite the query in a form that can be translated, or use AsEnumerable(), ToList(), or similar to explicitly bring data back to the client where it can then be further processed using LINQ-to-Objects.

EF Core 3.0 では .NET Standard 2.0 ではなく .NET Standard 2.1 がターゲットにされるEF Core 3.0 targets .NET Standard 2.1 rather than .NET Standard 2.0

問題 #15498 の追跡Tracking Issue #15498

重要

EF Core 3.1 では .NET Standard 2.0 が再度ターゲットにされています。EF Core 3.1 targets .NET Standard 2.0 again. このため、.NET Framework のサポートが復活します。This brings back support for .NET Framework.

以前の動作Old behavior

3.0 以前の EF Core の場合は、.NET Standard 2.0 がターゲットとされ、その標準をサポートするすべてのプラットフォーム (.NET Framework を含む) 上で実行されていました。Before 3.0, EF Core targeted .NET Standard 2.0 and would run on all platforms that support that standard, including .NET Framework.

新しい動作New behavior

3.0 以降の EF Core の場合は、.NET Standard 2.1 がターゲットとされ、この標準をサポートするすべてのプラットフォームで実行されます。Starting with 3.0, EF Core targets .NET Standard 2.1 and will run on all platforms that support this standard. これには、.NET Framework は含まれません。This does not include .NET Framework.

理由Why

これは、.NET Core やその他の最新の .NET プラットフォーム (Xamarin など) にエネルギーを集中するために .NET テクノロジ全体にわたって行われる戦略的な決定の一部です。This is part of a strategic decision across .NET technologies to focus energy on .NET Core and other modern .NET platforms, such as Xamarin.

軽減策Mitigations

EF Core 3.1 を使用します。Use EF Core 3.1.

Entity Framework Core が ASP.NET Core 共有フレームワークの一部ではなくなったEntity Framework Core is no longer part of the ASP.NET Core shared framework

問題 Announcements#325 の追跡Tracking Issue Announcements#325

以前の動作Old behavior

ASP.NET Core 3.0 より前では、パッケージ参照を Microsoft.AspNetCore.App または Microsoft.AspNetCore.All に追加したときに、EF Core と、SQL Server プロバイダーのような EF Core データ プロバイダーの一部が含まれました。Before ASP.NET Core 3.0, when you added a package reference to Microsoft.AspNetCore.App or Microsoft.AspNetCore.All, it would include EF Core and some of the EF Core data providers like the SQL Server provider.

新しい動作New behavior

3.0 以降では、ASP.NET Core 共有フレームワークには、EF Core も、いずれの EF Core データ プロバイダーも含まれません。Starting in 3.0, the ASP.NET Core shared framework doesn't include EF Core or any EF Core data providers.

理由Why

この変更の前では、アプリケーションのターゲットが ASP.NET Core であるか SQL Server であるかに応じて、EF Core を取得するには異なる手順が必要でした。Before this change, getting EF Core required different steps depending on whether the application targeted ASP.NET Core and SQL Server or not. また、ASP.NET Core のアップグレードでは、必ずしも適切だとは言えない、EF Core と SQL Server プロバイダーのアップグレードが強制されました。Also, upgrading ASP.NET Core forced the upgrade of EF Core and the SQL Server provider, which isn't always desirable.

この変更では、EF Core の取得のエクスペリエンスは、.NET の実装とアプリケーションの種類がサポートされる、すべてのプロバイダーで同じになります。With this change, the experience of getting EF Core is the same across all providers, supported .NET implementations and application types. また、開発者は、EF Core と EF Core データ プロバイダーのアップグレードのタイミングを正確に制御できるようになりました。Developers can also now control exactly when EF Core and EF Core data providers are upgraded.

軽減策Mitigations

ASP.NET Core 3.0 アプリケーションまたはその他のサポートされるアプリケーションで EF Core を使用するには、アプリケーションで使用される EF Core データベース プロバイダーにパッケージ参照を明示的に追加します。To use EF Core in an ASP.NET Core 3.0 application or any other supported application, explicitly add a package reference to the EF Core database provider that your application will use.

EF Core のコマンドライン ツールである dotnet ef が .NET Core SDK の一部ではなくなったThe EF Core command-line tool, dotnet ef, is no longer part of the .NET Core SDK

問題 #14016 の追跡Tracking Issue #14016

以前の動作Old behavior

3.0 より前は dotnet ef ツールが .NET Core SDK に含まれており、追加の手順を必要とせずに、任意のプロジェクトのコマンド ラインから簡単に使用できました。Before 3.0, the dotnet ef tool was included in the .NET Core SDK and was readily available to use from the command line from any project without requiring extra steps.

新しい動作New behavior

3.0 以降は .NET SDK に dotnet ef ツールが含まれないため、これを使用するにはローカルまたはグローバルなツールとして明示的にインストールする必要があります。Starting in 3.0, the .NET SDK does not include the dotnet ef tool, so before you can use it you have to explicitly install it as a local or global tool.

理由Why

この変更により、dotnet ef を通常の .NET CLI ツールとして NuGet 上で配信したり更新したりできるようになります。これは EF Core 3.0 も常に NuGet パッケージとして配信されるという事実と一致します。This change allows us to distribute and update dotnet ef as a regular .NET CLI tool on NuGet, consistent with the fact that the EF Core 3.0 is also always distributed as a NuGet package.

軽減策Mitigations

移行の管理や DbContext のスキャフォールディングを行えるようにするには、dotnet-ef をグローバル ツールとしてインストールします。To be able to manage migrations or scaffold a DbContext, install dotnet-ef as a global tool:

  $ dotnet tool install --global dotnet-ef

ツール マニフェスト ファイルを使用してツールの依存関係として宣言するプロジェクトの依存関係を復元するときに、ローカルなツールとして取得することもできます。You can also obtain it a local tool when you restore the dependencies of a project that declares it as a tooling dependency using a tool manifest file.

FromSql、ExecuteSql、および ExecuteSqlAsync の名前変更FromSql, ExecuteSql, and ExecuteSqlAsync have been renamed

問題 #10996 の追跡Tracking Issue #10996

以前の動作Old behavior

EF Core 3.0 より前のバージョンでは、通常の文字列または SQL およびパラメーターに挿入する必要がある文字列で使用するために、これらのメソッド名がオーバーロードされました。Before EF Core 3.0, these method names were overloaded to work with either a normal string or a string that should be interpolated into SQL and parameters.

新しい動作New behavior

EF Core 3.0 以降では、FromSqlRawExecuteSqlRaw、および ExecuteSqlRawAsync を使用して、パラメーターがクエリ文字列とは別に渡される、パラメーター化クエリが作成されます。Starting with EF Core 3.0, use FromSqlRaw, ExecuteSqlRaw, and ExecuteSqlRawAsync to create a parameterized query where the parameters are passed separately from the query string. 次に例を示します。For example:

context.Products.FromSqlRaw(
    "SELECT * FROM Products WHERE Name = {0}",
    product.Name);

FromSqlInterpolatedExecuteSqlInterpolated、および ExecuteSqlInterpolatedAsync を使用して、パラメーターが挿入クエリ文字列の一部として渡されるパラメーター化クエリを作成します。Use FromSqlInterpolated, ExecuteSqlInterpolated, and ExecuteSqlInterpolatedAsync to create a parameterized query where the parameters are passed as part of an interpolated query string. 次に例を示します。For example:

context.Products.FromSqlInterpolated(
    $"SELECT * FROM Products WHERE Name = {product.Name}");

上記のクエリはどちらも、同じ SQL パラメーターを持つ同じパラメーター化 SQL が生成されることに注意してください。Note that both of the queries above will produce the same parameterized SQL with the same SQL parameters.

理由Why

このようなメソッド オーバーロードは、挿入文字列メソッドを呼び出すつもりが、誤って raw 文字列メソッドを非常に簡単に呼び出せてしまいます。その逆も同様です。Method overloads like this make it very easy to accidentally call the raw string method when the intent was to call the interpolated string method, and the other way around. これは、クエリをパラメーター化する必要があるときに、パラメーター化されない結果になる場合があります。This could result in queries not being parameterized when they should have been.

軽減策Mitigations

新しいメソッド名を使用するように切り替えます。Switch to use the new method names.

FromSql メソッドをストアド プロシージャと共に使用して構成することができないFromSql method when used with stored procedure cannot be composed

問題 #15392 の追跡Tracking Issue #15392

以前の動作Old behavior

3.0 EF Core より前では、FromSql メソッドにより、渡された SQL を構成できるかどうかの検出が試行されていました。Before EF Core 3.0, FromSql method tried to detect if the passed SQL can be composed upon. SQL がストアド プロシージャのように非コンポーザブルである場合、クライアント評価が行われていました。It did client evaluation when the SQL was non-composable like a stored procedure. 次のクエリは、サーバー上でストアド プロシージャを実行し、クライアント側で FirstOrDefault を実行することで機能していました。The following query worked by running the stored procedure on the server and doing FirstOrDefault on the client side.

context.Products.FromSqlRaw("[dbo].[Ten Most Expensive Products]").FirstOrDefault();

新しい動作New behavior

EF Core 3.0 以降では、SQL の解析は試行されません。Starting with EF Core 3.0, EF Core will not try to parse the SQL. そのため、FromSqlRaw/FromSqlInterpolated の後に構成する場合、EF Core では、サブ クエリを実行することで SQL が構成されます。So if you are composing after FromSqlRaw/FromSqlInterpolated, then EF Core will compose the SQL by causing sub query. したがって、構成でストアド プロシージャを使用している場合は、無効な SQL 構文の例外が発生します。So if you are using a stored procedure with composition then you will get an exception for invalid SQL syntax.

理由Why

EF Core 3.0 では、自動クライアント評価はサポートされていません。これは、ここで説明するように、エラーが発生しやすいためです。EF Core 3.0 does not support automatic client evaluation, since it was error prone as explained here.

軽減策Mitigation

FromSqlRaw/FromSqlInterpolated でストアド プロシージャを使用している場合は、それを構成できないことがわかっているので、サーバー側での構成を回避するために、FromSql メソッド呼び出しの直後に AsEnumerable/AsAsyncEnumerable を追加します。If you are using a stored procedure in FromSqlRaw/FromSqlInterpolated, you know that it cannot be composed upon, so you can add AsEnumerable/AsAsyncEnumerable right after the FromSql method call to avoid any composition on server side.

context.Products.FromSqlRaw("[dbo].[Ten Most Expensive Products]").AsEnumerable().FirstOrDefault();

FromSql メソッドはクエリのルートでのみ指定できるFromSql methods can only be specified on query roots

問題 #15704 の追跡Tracking Issue #15704

以前の動作Old behavior

EF Core 3.0 以前は、クエリ内の任意の場所で FromSql メソッドを指定できました。Before EF Core 3.0, the FromSql method could be specified anywhere in the query.

新しい動作New behavior

EF Core 3.0 以降、新しい FromSqlRaw および FromSqlInterpolated メソッド (FromSql の置き換え) は、クエリのルート上でのみ (つまり DbSet<> で直接) 指定できます。Starting with EF Core 3.0, the new FromSqlRaw and FromSqlInterpolated methods (which replace FromSql) can only be specified on query roots, i.e. directly on the DbSet<>. 他の場所でそれらを指定しようとすると、コンパイル エラーが発生します。Attempting to specify them anywhere else will result in a compilation error.

理由Why

DbSet 以外の任意の場所で FromSql を指定しても、さらなる意味や価値が追加されることはなく、特定のシナリオではあいまいさの原因となる可能性があります。Specifying FromSql anywhere other than on a DbSet had no added meaning or added value, and could cause ambiguity in certain scenarios.

軽減策Mitigations

FromSql の呼び出し場所を移動して、それらが適用される DbSet 上で直接実行されるようにする必要があります。FromSql invocations should be moved to be directly on the DbSet to which they apply.

追跡なしのクエリでは、識別子の解決が実行されなくなったNo-tracking queries no longer perform identity resolution

問題 #13518 の追跡Tracking Issue #13518

以前の動作Old behavior

EF Core 3.0 以前の場合は、指定した型と ID を持つエンティティが出現するたびに同じエンティティ インスタンスが使用されます。Before EF Core 3.0, the same entity instance would be used for every occurrence of an entity with a given type and ID. これは、追跡クエリの動作と一致します。This matches the behavior of tracking queries. たとえば、このクエリはFor example, this query:

var results = context.Products.Include(e => e.Category).AsNoTracking().ToList();

指定したカテゴリに関連付けられている各 Category に対して同じ Product インスタンスが返されます。would return the same Category instance for each Product that is associated with the given category.

新しい動作New behavior

EF Core 3.0 以降では、指定した型と ID を持つエンティティが、返されたグラフ内の異なる場所で検出されると、それぞれ異なるエンティティ インスタンスが作成されます。Starting with EF Core 3.0, different entity instances will be created when an entity with a given type and ID is encountered at different places in the returned graph. たとえば、上記のクエリでは、2 つの製品が同じカテゴリに関連付けられている場合でも、各 Product に対して新しい Category インスタンスが返されるようになります。For example, the query above will now return a new Category instance for each Product even when two products are associated with the same category.

理由Why

識別子の解決 (つまり、エンティティの型と ID が以前に検出されたエンティティと同じであることを確認する) を行う場合は、パフォーマンスおよびメモリのオーバーヘッドが増大します。Identity resolution (that is, determining that an entity has the same type and ID as a previously encountered entity) adds additional performance and memory overhead. これは、通常、最初の場所で追跡なしのクエリが使用されている理由に矛盾しています。This usually runs counter to why no-tracking queries are used in the first place. また、識別子の解決は有用なこともありますが、エンティティをシリアル化してクライアントに送信する場合 (追跡なしのクエリでは一般的な処理) は必要ありません。Also, while identity resolution can sometimes be useful, it is not needed if the entities are to be serialized and sent to a client, which is common for no-tracking queries.

軽減策Mitigations

識別子の解決が必要な場合は、追跡クエリを使用します。Use a tracking query if identity resolution is required.

クエリの実行がデバッグ レベルでログに記録される 元に戻されますQuery execution is logged at Debug level Reverted

問題 #14523 の追跡Tracking Issue #14523

EF Core 3.0 の新しい構成では、あらゆるイベントのログ レベルをアプリケーションによって指定できるため、この変更は元に戻されます。We reverted this change because new configuration in EF Core 3.0 allows the log level for any event to be specified by the application. たとえば、SQL のログ記録を Debug に切り替えるには、OnConfiguring または AddDbContext で明示的にレベルを構成します。For example, to switch logging of SQL to Debug, explicitly configure the level in OnConfiguring or AddDbContext:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseSqlServer(connectionString)
        .ConfigureWarnings(c => c.Log((RelationalEventId.CommandExecuting, LogLevel.Debug)));

一時キーの値がエンティティ インスタンスに設定されなくなったTemporary key values are no longer set onto entity instances

問題 #12378 の追跡Tracking Issue #12378

以前の動作Old behavior

EF Core 3.0 より前では、後で実際の値がデータベースによって生成される、すべてのキー プロパティに一時的な値が割り当てられていました。Before EF Core 3.0, temporary values were assigned to all key properties that would later have a real value generated by the database. 通常、これらの一時的な値は大きい負の数値でした。Usually these temporary values were large negative numbers.

新しい動作New behavior

3.0 以降では、EF Core で、エンティティの追跡情報の一部として一時キーの値が格納され、キー プロパティ自体はそのままになります。Starting with 3.0, EF Core stores the temporary key value as part of the entity's tracking information, and leaves the key property itself unchanged.

理由Why

この変更は、何らかの DbContext インスタンスによって以前に追跡されたエンティティが、別の DbContext インスタンスに移動されるときに、一時キーの値が誤って永続的なものにならないようにするために行われました。This change was made to prevent temporary key values from erroneously becoming permanent when an entity that has been previously tracked by some DbContext instance is moved to a different DbContext instance.

軽減策Mitigations

主キーの値を外部キーに割り当てて、エンティティ間の関連付けを形成するアプリケーションは、主キーがストアで生成されており、Added 状態のエンティティに属している場合、以前の動作に依存する可能性があります。Applications that assign primary key values onto foreign keys to form associations between entities may depend on the old behavior if the primary keys are store-generated and belong to entities in the Added state. これは、次のようにして回避できます。This can be avoided by:

  • ストア生成キーを使用しない。Not using store-generated keys.
  • 外部キーの値を設定するのではなく、ナビゲーション プロパティを設定してリレーションシップを形成する。Setting navigation properties to form relationships instead of setting foreign key values.
  • エンティティの追跡情報から実際の一時キーの値を取得する。Obtain the actual temporary key values from the entity's tracking information. たとえば、context.Entry(blog).Property(e => e.Id).CurrentValue では、blog.Id 自体が設定されていない場合でも、一時的な値が返されます。For example, context.Entry(blog).Property(e => e.Id).CurrentValue will return the temporary value even though blog.Id itself hasn't been set.

DetectChanges でストア生成キーの値が優先されるDetectChanges honors store-generated key values

問題 #14616 の追跡Tracking Issue #14616

以前の動作Old behavior

EF Core 3.0 より前では、DetectChanges によって検出された追跡対象外のエンティティが Added 状態で追跡され、SaveChanges が呼び出されたときに新しい行として挿入されました。Before EF Core 3.0, an untracked entity found by DetectChanges would be tracked in the Added state and inserted as a new row when SaveChanges is called.

新しい動作New behavior

EF Core 3.0 以降では、エンティティで生成されたキーの値を使用し、何らかのキーの値が設定されている場合、そのエンティティは Modified 状態で追跡されます。Starting with EF Core 3.0, if an entity is using generated key values and some key value is set, then the entity will be tracked in the Modified state. つまり、エンティティの行が存在していると見なされ、SaveChanges の呼び出し時に更新されます。This means that a row for the entity is assumed to exist and it will be updated when SaveChanges is called. キーの値が設定されていないか、エンティティ型で生成されたキーが使用されない場合、新しいエンティティは引き続き、以前のバージョンと同様に Added として追跡されます。If the key value isn't set, or if the entity type isn't using generated keys, then the new entity will still be tracked as Added as in previous versions.

理由Why

この変更は、ストア生成キーの使用中に、切り離されたエンティティ グラフをより簡単に一貫して操作できるようにするために行われました。This change was made to make it easier and more consistent to work with disconnected entity graphs while using store-generated keys.

軽減策Mitigations

エンティティ型が生成されたキーを使用するように構成されているものの、キーの値が新しいインスタンスに対して明示的に設定されている場合、この変更によってアプリケーションが中断される可能性があります。This change can break an application if an entity type is configured to use generated keys but key values are explicitly set for new instances. この問題を解決するには、キー プロパティで生成された値が使用されないように明示的に構成します。The fix is to explicitly configure the key properties to not use generated values. たとえば、fluent API を使用する場合は、次のようになります。For example, with the fluent API:

modelBuilder
    .Entity<Blog>()
    .Property(e => e.Id)
    .ValueGeneratedNever();

データ注釈を使用する場合は、次のようになります。Or with data annotations:

[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string Id { get; set; }

既定で連鎖削除がすぐに行われるようになったCascade deletions now happen immediately by default

問題 #10114 の追跡Tracking Issue #10114

以前の動作Old behavior

3.0 より前では、EF Core で適用された連鎖操作 (必要なプリンシパルが削除されたか、必要なプリンシパルへのリレーションシップが切断されたときに依存エンティティを削除する) は、SaveChanges が呼び出されるまで行われませんでした。Before 3.0, EF Core applied cascading actions (deleting dependent entities when a required principal is deleted or when the relationship to a required principal is severed) did not happen until SaveChanges was called.

新しい動作New behavior

3.0 以降では、EF Core で、トリガー条件が検出されるとすぐに連鎖操作が適用されます。Starting with 3.0, EF Core applies cascading actions as soon as the triggering condition is detected. たとえば、プリンシパル エンティティを削除するために context.Remove() を呼び出すと、すべての追跡対象の関連する必要な依存関係もすぐに Deleted に設定されます。For example, calling context.Remove() to delete a principal entity will result in all tracked related required dependents also being set to Deleted immediately.

理由Why

この変更は、SaveChanges が呼び出される_前に_どのエンティティが削除されるかを把握することが重要である、データ バインディングおよび監査シナリオのエクスペリエンスを向上させるために行われました。This change was made to improve the experience for data binding and auditing scenarios where it is important to understand which entities will be deleted before SaveChanges is called.

軽減策Mitigations

context.ChangeTracker の設定を使用して、以前の動作を復元することができます。The previous behavior can be restored through settings on context.ChangeTracker. 次に例を示します。For example:

context.ChangeTracker.CascadeDeleteTiming = CascadeTiming.OnSaveChanges;
context.ChangeTracker.DeleteOrphansTiming = CascadeTiming.OnSaveChanges;

問題 #18022 の追跡Tracking issue #18022

以前の動作Old behavior

3.0 より前では、Include 演算子を使用してコレクション ナビゲーションを一括で読み込むと、関連するエンティティ型ごとに 1 つずつ、リレーショナル データベースで複数のクエリが生成されていました。Before 3.0, eagerly loading collection navigations via Include operators caused multiple queries to be generated on relational database, one for each related entity type.

新しい動作New behavior

3.0 以降の EF Core では、リレーショナル データベースで結合を使用した単一のクエリが生成されます。Starting with 3.0, EF Core generates a single query with JOINs on relational databases.

理由Why

単一の LINQ クエリを実装するために複数のクエリを実行すると、多くの問題が発生していました。これらの問題には、複数のデータベース ラウンドトリップが必要になった際のパフォーマンスの低下や、各クエリによってデータベースの異なる状態が観察された際のデータの一貫性の問題などが含まれます。Issuing multiple queries to implement a single LINQ query caused numerous issues, including negative performance as multiple database roundtrips were necessary, and data coherency issues as each query could observe a different state of the database.

軽減策Mitigations

技術的に、これは破壊的変更ではありませんが、コレクション ナビゲーションで単一のクエリに多数の Include 演算子が含まれている場合、アプリケーションのパフォーマンスに大きな影響を及ぼす可能性があります。While technically this is not a breaking change, it could have a considerable effect on application performance when a single query contains a large number of Include operator on collection navigations. 詳細情報、およびより効率的な方法でクエリを再記述する方法については、こちらのコメントを参照してくださいSee this comment for more information and for rewriting queries in a more efficient way.

**

DeleteBehavior.Restrict のセマンティクスがクリーンになりましたDeleteBehavior.Restrict has cleaner semantics

問題 #12661 の追跡Tracking Issue #12661

以前の動作Old behavior

3.0 以前は、DeleteBehavior.Restrict により Restrict セマンティクスでデータベースに外部キーが作成されましたが、内部の修正がどのように変更されたのかがはっきりしませんでした。Before 3.0, DeleteBehavior.Restrict created foreign keys in the database with Restrict semantics, but also changed internal fixup in a non-obvious way.

新しい動作New behavior

3.0 以降では、DeleteBehavior.Restrict により Restrict セマンティクスで外部キーが作成されます。つまり、カスケードがありません。EF 内部修正には影響を出さず、制約違反で例外がスローされます。Starting with 3.0, DeleteBehavior.Restrict ensures that foreign keys are created with Restrict semantics--that is, no cascades; throw on constraint violation--without also impacting EF internal fixup.

理由Why

この変更は、副作用を出さず、直観的に DeleteBehavior を使用するために行われました。This change was made to improve the experience for using DeleteBehavior in an intuitive manner, without unexpected side-effects.

軽減策Mitigations

DeleteBehavior.ClientNoAction を使用し、以前の動作を復元できます。The previous behavior can be restored by using DeleteBehavior.ClientNoAction.

クエリ型がエンティティ型と統合されるQuery types are consolidated with entity types

問題 #14194 の追跡Tracking Issue #14194

以前の動作Old behavior

EF Core 3.0 より前では、クエリ型は、構造化された方法で主キーが定義されないデータのクエリを実行するための手段でした。Before EF Core 3.0, query types were a means to query data that doesn't define a primary key in a structured way. つまり、クエリ型は、キーが利用できるときに (テーブルからの可能性が高くなりますが、ビューからの可能性もあります) 通常のエンティティ型が使用された場合に、キーなしの (ビューからの可能性が高くなりますが、テーブルからの可能性もあります) エンティティ型をマップするために使用されました。That is, a query type was used for mapping entity types without keys (more likely from a view, but possibly from a table) while a regular entity type was used when a key was available (more likely from a table, but possibly from a view).

新しい動作New behavior

クエリ型は、現在、主キーなしの単なるエンティティ型になります。A query type now becomes just an entity type without a primary key. キーなしのエンティティ型の機能は、以前のバージョンのクエリ型と同じです。Keyless entity types have the same functionality as query types in previous versions.

理由Why

この変更は、クエリ型の目的に関する混乱を減らすために行われました。This change was made to reduce the confusion around the purpose of query types. つまり、これらはキーなしのエンティティ型であるため、本質的には読み取り専用となりますが、単にエンティティ型を読み取り専用にする必要があるという理由で使用しないでください。Specifically, they are keyless entity types and they are inherently read-only because of this, but they should not be used just because an entity type needs to be read-only. 同様に、これらは多くの場合、ビューにマップされますが、これは、単にビューでは多くの場合、キーが定義されないためです。Likewise, they are often mapped to views, but this is only because views often don't define keys.

軽減策Mitigations

API の以下の部分は使用されなくなりました。The following parts of the API are now obsolete:

  • ModelBuilder.Query<>() - 代わりに ModelBuilder.Entity<>().HasNoKey() を呼び出して、エンティティ型をキーなしとしてマークする必要があります。ModelBuilder.Query<>() - Instead ModelBuilder.Entity<>().HasNoKey() needs to be called to mark an entity type as having no keys. これは、規則により、主キーは必要であるが、規則と一致しない場合に構成エラーを回避するようにはまだ構成されません。This would still not be configured by convention to avoid misconfiguration when a primary key is expected, but doesn't match the convention.
  • DbQuery<> - 代わりに DbSet<> を使用する必要があります。DbQuery<> - Instead DbSet<> should be used.
  • DbContext.Query<>() - 代わりに DbContext.Set<>() を使用する必要があります。DbContext.Query<>() - Instead DbContext.Set<>() should be used.
  • IQueryTypeConfiguration<TQuery> - 代わりに IEntityTypeConfiguration<TEntity>** を使用する必要があります。IQueryTypeConfiguration<TQuery> - Instead IEntityTypeConfiguration<TEntity>** should be used.

注意

プロパティがすべて null に設定されているキーなしエンティティのクエリを実行する場合に発生する 3.x の問題により、エンティティではなく null が返されます。この問題がご自身のシナリオに当てはまる場合は、ロジックを追加して、結果に含まれる null の処理も行ってください。Due to an issue in 3.x when querying keyless entities that have all properties set to null a null will be returned instead of an entity, if this issue is applicable to your scenario also add logic to handle null in results.

所有型のリレーションシップ用の構成 API が変更されたConfiguration API for owned type relationships has changed

問題 #12444 の追跡 問題 #9148 の追跡 問題 #14153 の追跡Tracking Issue #12444 Tracking Issue #9148 Tracking Issue #14153

以前の動作Old behavior

EF Core 3.0 より前では、所有リレーションシップの構成は、OwnsOne または OwnsMany の呼び出し直後に実行されました。Before EF Core 3.0, configuration of the owned relationship was performed directly after the OwnsOne or OwnsMany call.

新しい動作New behavior

EF Core 3.0 以降では、fluent API で、WithOwner() を使用して、所有者に対してナビゲーション プロパティが構成されるようになりました。Starting with EF Core 3.0, there is now fluent API to configure a navigation property to the owner using WithOwner(). 次に例を示します。For example:

modelBuilder.Entity<Order>.OwnsOne(e => e.Details).WithOwner(e => e.Order);

現在、所有者と所有型間のリレーションシップに関する構成は、他のリレーションシップの構成方法と同様、WithOwner() 後にチェーンする必要があります。The configuration related to the relationship between owner and owned should now be chained after WithOwner() similarly to how other relationships are configured. 一方、所有型自体の構成は引き続き、OwnsOne()/OwnsMany() 後にチェーンされます。While the configuration for the owned type itself would still be chained after OwnsOne()/OwnsMany(). 次に例を示します。For example:

modelBuilder.Entity<Order>.OwnsOne(e => e.Details, eb =>
    {
        eb.WithOwner()
            .HasForeignKey(e => e.AlternateId)
            .HasConstraintName("FK_OrderDetails");
            
        eb.ToTable("OrderDetails");
        eb.HasKey(e => e.AlternateId);
        eb.HasIndex(e => e.Id);

        eb.HasOne(e => e.Customer).WithOne();

        eb.HasData(
            new OrderDetails
            {
                AlternateId = 1,
                Id = -1
            });
    });

さらに所有型ターゲットでの Entity()HasOne()、または Set() の呼び出しでは、例外がスローされるようになります。Additionally calling Entity(), HasOne(), or Set() with an owned type target will now throw an exception.

理由Why

この変更は、所有型自体と、所有型_へのリレーションシップ_の構成を明確に分離するために行われました。This change was made to create a cleaner separation between configuring the owned type itself and the relationship to the owned type. これにより、HasForeignKey のようなメソッドに関するあいまいさと混乱はなくなります。This in turn removes ambiguity and confusion around methods like HasForeignKey.

軽減策Mitigations

上記の例で示すように、新しい API サーフェスを使用するように、所有型リレーションシップの構成を変更します。Change configuration of owned type relationships to use the new API surface as shown in the example above.

プリンシパルとテーブルを共有する依存エンティティが省略可能になりましたDependent entities sharing the table with the principal are now optional

問題 #9005 の追跡Tracking Issue #9005

以前の動作Old behavior

次のモデルがあるとします。Consider the following model:

public class Order
{
    public int Id { get; set; }
    public int CustomerId { get; set; }
    public OrderDetails Details { get; set; }
}

public class OrderDetails
{
    public int Id { get; set; }
    public string ShippingAddress { get; set; }
}

EF Core 3.0 より前のバージョンでは、OrderDetailsOrder によって所有されている場合、または同じテーブルに明示的にマップされている場合、新しい Order を追加する場合には常に OrderDetails インスタンスが必要でした。Before EF Core 3.0, if OrderDetails is owned by Order or explicitly mapped to the same table then an OrderDetails instance was always required when adding a new Order.

新しい動作New behavior

EF Core 3.0 以降では、OrderDetails なしで Order を追加することができ、主キー以外のすべての OrderDetails プロパティが NULL 値が許可される列にマップされます。Starting with 3.0, EF Core allows to add an Order without an OrderDetails and maps all of the OrderDetails properties except the primary key to nullable columns. OrderDetails は、必要なプロパティのいずれにも値がない場合、または主キー以外に必要なプロパティがなく、すべてのプロパティが null の場合、EF Core のクエリの実行時に null に設定されます。When querying EF Core sets OrderDetails to null if any of its required properties doesn't have a value or if it has no required properties besides the primary key and all properties are null.

軽減策Mitigations

モデルに省略可能なすべての列と依存関係を共有するテーブルがあるが、それを指すナビゲーションが null になることが想定されていない場合は、ナビゲーションが null の場合のケースを処理するようにアプリケーションを変更する必要があります。If your model has a table sharing dependent with all optional columns, but the navigation pointing to it is not expected to be null then the application should be modified to handle cases when the navigation is null. これができない場合は、必要なプロパティをエンティティ型に追加するか、少なくとも 1 つのプロパティに割り当てられている値が null 以外である必要があります。If this is not possible a required property should be added to the entity type or at least one property should have a non-null value assigned to it.

同時実行トークン列とテーブルを共有するすべてのエンティティをプロパティにマップする必要があります。All entities sharing a table with a concurrency token column have to map it to a property

問題 #14154 の追跡Tracking Issue #14154

以前の動作Old behavior

次のモデルがあるとします。Consider the following model:

public class Order
{
    public int Id { get; set; }
    public int CustomerId { get; set; }
    public byte[] Version { get; set; }
    public OrderDetails Details { get; set; }
}

public class OrderDetails
{
    public int Id { get; set; }
    public string ShippingAddress { get; set; }
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Order>()
        .Property(o => o.Version).IsRowVersion().HasColumnName("Version");
}

EF Core 3.0 より前のバージョンでは、OrderDetailsOrder によって所有されている場合、または同じテーブルに明示的にマップされている場合、OrderDetails だけを更新してもクライアント上の Version 値は更新されず、次回の更新が失敗します。Before EF Core 3.0, if OrderDetails is owned by Order or explicitly mapped to the same table then updating just OrderDetails will not update Version value on client and the next update will fail.

新しい動作New behavior

EF Core 3.0 以降では、新しい Version 値が OrderDetails を所有している場合には Order に伝達されます。Starting with 3.0, EF Core propagates the new Version value to Order if it owns OrderDetails. それ以外の場合は、モデルの検証中に例外がスローされます。Otherwise an exception is thrown during model validation.

理由Why

この変更は、エンティティの 1 つだけが同じテーブルにマップされている場合に、古い同時実行トークン値が更新されるのを回避するために行われました。This change was made to avoid a stale concurrency token value when only one of the entities mapped to the same table is updated.

軽減策Mitigations

テーブルを共有するすべてのエンティティには、同時実行トークン列にマップされるプロパティを含める必要があります。All entities sharing the table have to include a property that is mapped to the concurrency token column. シャドウ状態で作成することができます。It's possible the create one in shadow-state:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<OrderDetails>()
        .Property<byte[]>("Version").IsRowVersion().HasColumnName("Version");
}

所有エンティティは、所有者がいないと、追跡クエリを使用してクエリを実行することができないOwned entities cannot be queried without the owner using a tracking query

問題 #18876 の追跡Tracking Issue #18876

以前の動作Old behavior

EF Core 3.0 より前のバージョンでは、所有エンティティに対しても他のナビゲーションと同じようにクエリを実行することができました。Before EF Core 3.0, the owned entities could be queried as any other navigation.

context.People.Select(p => p.Address);

新しい動作New behavior

EF Core 3.0 以降では、追跡クエリで所有者のいない所有エンティティが提示されると、スローされます。Starting with 3.0, EF Core will throw if a tracking query projects an owned entity without the owner.

理由Why

所有エンティティは所有者なしでは操作できません。そのため、このようにクエリを実行するほとんどのケースでは、エラーになります。Owned entities cannot be manipulated without the owner, so in the vast majority of cases querying them in this way is an error.

軽減策Mitigations

所有エンティティを後で変更するように追跡する必要がある場合は、所有者をクエリに含める必要があります。If the owned entity should be tracked to be modified in any way later then the owner should be included in the query.

それ以外の場合は、AsNoTracking() の呼び出しを追加します。Otherwise add an AsNoTracking() call:

context.People.Select(p => p.Address).AsNoTracking();

マップされていない型から継承されたプロパティは、すべての派生型の 1 つの列にマップされるようになりましたInherited properties from unmapped types are now mapped to a single column for all derived types

問題 #13998 の追跡Tracking Issue #13998

以前の動作Old behavior

次のモデルがあるとします。Consider the following model:

public abstract class EntityBase
{
    public int Id { get; set; }
}

public abstract class OrderBase : EntityBase
{
    public int ShippingAddress { get; set; }
}

public class BulkOrder : OrderBase
{
}

public class Order : OrderBase
{
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Ignore<OrderBase>();
    modelBuilder.Entity<EntityBase>();
    modelBuilder.Entity<BulkOrder>();
    modelBuilder.Entity<Order>();
}

EF Core 3.0 より前のバージョンでは、ShippingAddress プロパティは既定で BulkOrderOrder の個別の列にマップされていました。Before EF Core 3.0, the ShippingAddress property would be mapped to separate columns for BulkOrder and Order by default.

新しい動作New behavior

EF Core 3.0 以降では、ShippingAddress に対して 1 つの列だけが作成されます。Starting with 3.0, EF Core only creates one column for ShippingAddress.

理由Why

以前の動作は予期しないものでした。The old behavoir was unexpected.

軽減策Mitigations

プロパティは、派生型の個別の列に引き続き明示的にマップすることができます。The property can still be explicitly mapped to separate column on the derived types:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Ignore<OrderBase>();
    modelBuilder.Entity<EntityBase>();
    modelBuilder.Entity<BulkOrder>()
        .Property(o => o.ShippingAddress).HasColumnName("BulkShippingAddress");
    modelBuilder.Entity<Order>()
        .Property(o => o.ShippingAddress).HasColumnName("ShippingAddress");
}

外部キー プロパティの規則がプリンシパル プロパティと同じ名前と一致しなくなったThe foreign key property convention no longer matches same name as the principal property

問題 #13274 の追跡Tracking Issue #13274

以前の動作Old behavior

次のモデルがあるとします。Consider the following model:

public class Customer
{
    public int CustomerId { get; set; }
    public ICollection<Order> Orders { get; set; }
}

public class Order
{
    public int Id { get; set; }
    public int CustomerId { get; set; }
}

EF Core 3.0 より前では、規則により、外部キーで CustomerId プロパティが使用されました。Before EF Core 3.0, the CustomerId property would be used for the foreign key by convention. しかし、Order が所有型である場合、CustomerId も主キーとマークされ、これは通常、期待されることではありません。However, if Order is an owned type, then this would also make CustomerId the primary key and this isn't usually the expectation.

新しい動作New behavior

EF Core 3.0 以降では、プリンシパル プロパティと同じ名前である場合、規則により、外部キーに対するプロパティの使用は試行されません。Starting with 3.0, EF Core doesn't try to use properties for foreign keys by convention if they have the same name as the principal property. プリンシパル プロパティ名と連結されたプリンシパル型名、およびプリンシパル プロパティ名パターンと連結されたナビゲーション名は、引き続き一致します。Principal type name concatenated with principal property name, and navigation name concatenated with principal property name patterns are still matched. 次に例を示します。For example:

public class Customer
{
    public int Id { get; set; }
    public ICollection<Order> Orders { get; set; }
}

public class Order
{
    public int Id { get; set; }
    public int CustomerId { get; set; }
}
public class Customer
{
    public int Id { get; set; }
    public ICollection<Order> Orders { get; set; }
}

public class Order
{
    public int Id { get; set; }
    public int BuyerId { get; set; }
    public Customer Buyer { get; set; }
}

理由Why

この変更は、所有型に主キー プロパティが誤って定義されないようにするために行われました。This change was made to avoid erroneously defining a primary key property on the owned type.

軽減策Mitigations

プロパティを外部キーにする、したがって、主キーの一部にする予定だった場合は、そのように明示的に構成します。If the property was intended to be the foreign key, and hence part of the primary key, then explicitly configure it as such.

データベース接続は、これ以上使用されない場合、TransactionScope が完了する前に閉じられるようになりましたDatabase connection is now closed if not used anymore before the TransactionScope has been completed

問題 #14218 の追跡Tracking Issue #14218

以前の動作Old behavior

EF Core 3.0 より前のバージョンでは、コンテキストにより TransactionScope 内部で接続が開かれると、現在の TransactionScope がアクティブの間、接続が開いたままになります。Before EF Core 3.0, if the context opens the connection inside a TransactionScope, the connection remains open while the current TransactionScope is active.

using (new TransactionScope())
{
    using (AdventureWorks context = new AdventureWorks())
    {
        context.ProductCategories.Add(new ProductCategory());
        context.SaveChanges();

        // Old behavior: Connection is still open at this point

        var categories = context.ProductCategories().ToList();
    }
}

新しい動作New behavior

EF Core 3.0 以降では、使用が終了したらすぐに接続が閉じられます。Starting with 3.0, EF Core closes the connection as soon as it's done using it.

理由Why

この変更により、同じ TransactionScope で複数のコンテキストを使用できます。This change allows to use multiple contexts in the same TransactionScope. 新しい動作は、EF6 にも一致します。The new behavior also matches EF6.

軽減策Mitigations

接続を開いたままにする必要がある場合は、OpenConnection() を明示的に呼び出して、EF Core が途中で閉じないようにします。If the connection needs to remain open explicit call to OpenConnection() will ensure that EF Core doesn't close it prematurely:

using (new TransactionScope())
{
    using (AdventureWorks context = new AdventureWorks())
    {
        context.Database.OpenConnection();
        context.ProductCategories.Add(new ProductCategory());
        context.SaveChanges();

        var categories = context.ProductCategories().ToList();
        context.Database.CloseConnection();
    }
}

各プロパティで独立したメモリ内整数キー生成が使用されるEach property uses independent in-memory integer key generation

問題 #6872 の追跡Tracking Issue #6872

以前の動作Old behavior

EF Core 3.0 より前では、1 つの共有値ジェネレーターが、すべてのメモリ内整数キー プロパティで使用されていました。Before EF Core 3.0, one shared value generator was used for all in-memory integer key properties.

新しい動作New behavior

EF Core 3.0 以降では、各整数キー プロパティで、メモリ内データベースを使用するときに独自の値ジェネレーターが取得されます。Starting with EF Core 3.0, each integer key property gets its own value generator when using the in-memory database. また、データベースが削除された場合は、すべてのテーブルに対してキーの生成がリセットされます。Also, if the database is deleted, then key generation is reset for all tables.

理由Why

この変更は、実際のデータベース キー生成により近くなるようにメモリ内キー生成を調整するため、また、メモリ内データベースを使用するときに互いのテストを分離させる機能を向上させるために行われました。This change was made to align in-memory key generation more closely to real database key generation and to improve the ability to isolate tests from each other when using the in-memory database.

軽減策Mitigations

これにより、設定される特定のメモリ内キー値に依存しているアプリケーションが中断される可能性があります。This can break an application that is relying on specific in-memory key values to be set. 代わりに特定のキーの値に依存しないようにするか、あるいは新しい動作と一致するように更新することを検討します。Consider instead not relying on specific key values, or updating to match the new behavior.

バッキング フィールドが既定で使用されるBacking fields are used by default

問題 #12430 の追跡Tracking Issue #12430

以前の動作Old behavior

3.0 より前では、プロパティのバッキング フィールドがわかっていた場合でも、EF Core では引き続き、既定でプロパティの getter および setter メソッドを使用して、プロパティ値の読み取りと書き込みが行われました。Before 3.0, even if the backing field for a property was known, EF Core would still by default read and write the property value using the property getter and setter methods. ただし、バッキング フィールドが直接設定されることがわかっている場合のクエリの実行は例外です。The exception to this was query execution, where the backing field would be set directly if known.

新しい動作New behavior

EF Core 3.0 以降では、プロパティのバッキング フィールドがわかっている場合、バッキング フィールドを使用して、常に EF Core がそのプロパティの読み取りと書き込みを行います。Starting with EF Core 3.0, if the backing field for a property is known, then EF Core will always read and write that property using the backing field. アプリケーションが getter および setter メソッドにコード化された追加動作に依存している場合、これによりアプリケーションが中断される可能性があります。This could cause an application break if the application is relying on additional behavior coded into the getter or setter methods.

理由Why

この変更は、EF Core が、エンティティに関するデータベース操作の実行時に、既定でビジネス ロジックを誤ってトリガーしないようにするために行われました。This change was made to prevent EF Core from erroneously triggering business logic by default when performing database operations involving the entities.

軽減策Mitigations

3.0 より前の動作は、ModelBuilder のプロパティ アクセス モードの構成を通じて復元できます。The pre-3.0 behavior can be restored through configuration of the property access mode on ModelBuilder. 次に例を示します。For example:

modelBuilder.UsePropertyAccessMode(PropertyAccessMode.PreferFieldDuringConstruction);

複数の互換性があるバッキング フィールドが見つかった場合にスローされるThrow if multiple compatible backing fields are found

問題 #12523 の追跡Tracking Issue #12523

以前の動作Old behavior

EF Core 3.0 より前では、複数のフィールドが、プロパティのバッキング フィールドを見つけるための規則と一致した場合、何らかの優先順位に基づいて、1 つのフィールドが選択されました。Before EF Core 3.0, if multiple fields matched the rules for finding the backing field of a property, then one field would be chosen based on some precedence order. これにより、あいまいなケースで不適切なフィールドが使用される可能性があります。This could cause the wrong field to be used in ambiguous cases.

新しい動作New behavior

EF Core 3.0 以降では、複数のフィールドが同じプロパティと一致した場合、例外がスローされます。Starting with EF Core 3.0, if multiple fields are matched to the same property, then an exception is thrown.

理由Why

この変更は、1 つのフィールドのみが適切である可能性がある場合に、他のものより優先して暗黙的に 1 つのフィールドが使用されないようにするために行われました。This change was made to avoid silently using one field over another when only one can be correct.

軽減策Mitigations

あいまいなバッキング フィールドがあるプロパティでは、使用するフィールドを明示的に指定する必要があります。Properties with ambiguous backing fields must have the field to use specified explicitly. たとえば、fluent API を使用する場合、次のようになります。For example, using the fluent API:

modelBuilder
    .Entity<Blog>()
    .Property(e => e.Id)
    .HasField("_id");

フィールド専用プロパティの名前はフィールドの名前に一致する必要がありますField-only property names should match the field name

以前の動作Old behavior

EF Core 3.0 以前では、プロパティは文字列値により指定できました。 .NET 型でその名前のプロパティが見つからなかった場合、EF Core では、一般的な規則を使ってそれとフィールドの照合が試行されました。Before EF Core 3.0, a property could be specified by a string value and if no property with that name was found on the .NET type then EF Core would try to match it to a field using convention rules.

private class Blog
{
    private int _id;
    public string Name { get; set; }
}
modelBuilder
    .Entity<Blog>()
    .Property("Id");

新しい動作New behavior

EF Core 3.0 以降では、フィールド専用プロパティはフィールドの名前に厳密に一致する必要があります。Starting with EF Core 3.0, a field-only property must match the field name exactly.

modelBuilder
    .Entity<Blog>()
    .Property("_id");

理由Why

この変更は、同じような名前が付けられた 2 つのプロパティに同じフィールドが使用されるのを回避する目的で行われました。また、フィールド専用プロパティの照合規則を、CLR プロパティにマッピングされているプロパティの場合と同じにします。This change was made to avoid using the same field for two properties named similarly, it also makes the matching rules for field-only properties the same as for properties mapped to CLR properties.

軽減策Mitigations

フィールド専用プロパティには、それがマッピングされるフィールドと同じ名前を付ける必要があります。Field-only properties must be named the same as the field they are mapped to. EF Core 3.0 以降の今後のリリースでは、プロパティ名とは異なるフィールド名を明示的に構成できるように戻す予定です (問題 #15307 を参照)。In a future release of EF Core after 3.0, we plan to re-enable explicitly configuring a field name that is different from the property name (see issue #15307):

modelBuilder
    .Entity<Blog>()
    .Property("Id")
    .HasField("_id");

AddDbContext/AddDbContextPool で AddLogging および AddMemoryCache を呼び出さなくなりましたAddDbContext/AddDbContextPool no longer call AddLogging and AddMemoryCache

問題 #14756 の追跡Tracking Issue #14756

以前の動作Old behavior

EF Core 3.0 より前のバージョンでは、AddDbContext または AddDbContextPool を呼び出すと、AddLogging および AddMemoryCache への呼び出しを通じて、DI を使ってログ記録とメモリ キャッシュ サービスも登録されました。Before EF Core 3.0, calling AddDbContext or AddDbContextPool would also register logging and memory caching services with DI through calls to AddLogging and AddMemoryCache.

新しい動作New behavior

EF Core 3.0 以降、AddDbContextAddDbContextPool では、依存関係の挿入 (DI) を使ってこれらのサービスを登録しなくなります。Starting with EF Core 3.0, AddDbContext and AddDbContextPool will no longer register these services with Dependency Injection (DI).

理由Why

EF Core 3.0 では、これらのサービスをアプリケーションの DI コンテナーに含める必要がありません。EF Core 3.0 does not require that these services are in the application's DI container. ただし、ILoggerFactory がアプリケーションの DI コンテナーに登録された場合、それは引き続き EF Core によって使用されます。However, if ILoggerFactory is registered in the application's DI container, then it will still be used by EF Core.

軽減策Mitigations

ご自身のアプリケーションでこれらのサービスが必要な場合は、AddLogging または AddMemoryCache を使って、DI コンテナーで明示的にそれらを登録します。If your application needs these services, then register them explicitly with the DI container using AddLogging or AddMemoryCache.

AddEntityFramework* により、サイズ制限がある IMemoryCache が追加されるAddEntityFramework* adds IMemoryCache with a size limit

問題 #12905 の追跡Tracking Issue #12905

以前の動作Old behavior

EF Core 3.0 より前のバージョンでは、AddEntityFramework* メソッドを呼び出すと、サイズ制限のないメモリ キャッシュ サービスも DI に登録されていました。Before EF Core 3.0, calling AddEntityFramework* methods would also register memory caching services with DI without a size limit.

新しい動作New behavior

EF Core 3.0 以降では、AddEntityFramework* によって IMemoryCache サービスがサイズ制限付きで登録されます。Starting with EF Core 3.0, AddEntityFramework* will register an IMemoryCache service with a size limit. その後に追加された他のサービスが IMemoryCache に依存している場合は、既定の制限にすぐに達して、例外やパフォーマンスの低下が発生する可能性があります。If any other services added afterwards depend on IMemoryCache they can quickly reach the default limit causing exceptions or degraded performance.

理由Why

クエリ キャッシュ ロジックにバグがある場合、またはクエリが動的に生成される場合は、制限なしで IMemoryCache を使用すると、メモリ使用量が制御されなくなる可能性があります。Using IMemoryCache without a limit could result in uncontrolled memory usage if there is a bug in query caching logic or the queries are generated dynamically. 既定の制限を設定することで、DoS 攻撃の可能性を軽減できます。Having a default limit mitigates a potential DoS attack.

軽減策Mitigations

AddDbContext または AddDbContextPool も呼び出された場合、ほとんどの場合、AddEntityFramework* を呼び出す必要はありません。In most cases calling AddEntityFramework* is not necessary if AddDbContext or AddDbContextPool is called as well. したがって、最善の軽減策は、AddEntityFramework* の呼び出しを削除することです。Therefore, the best mitigation is to remove the AddEntityFramework* call.

ご自身のアプリケーションでこれらのサービスが必要な場合は、AddMemoryCache を使用する前に、IMemoryCache の実装を DI コンテナーに明示的に登録します。If your application needs these services, then register a IMemoryCache implementation explicitly with the DI container beforehand using AddMemoryCache.

DbContext.Entry でローカルの DetectChanges が実行されるようになったDbContext.Entry now performs a local DetectChanges

問題 #13552 の追跡Tracking Issue #13552

以前の動作Old behavior

EF Core 3.0 より前では、DbContext.Entry を呼び出すと、追跡対象のすべてのエンティティで変更が検出されました。Before EF Core 3.0, calling DbContext.Entry would cause changes to be detected for all tracked entities. これにより、EntityEntry で示された状態が確実に最新のものとなりました。This ensured that the state exposed in the EntityEntry was up-to-date.

新しい動作New behavior

EF Core 3.0 以降では、DbContext.Entry の呼び出しで、特定のエンティティと、それに関連する追跡対象のプリンシパル エンティティでの変更のみの検出が試行されるようになります。Starting with EF Core 3.0, calling DbContext.Entry will now only attempt to detect changes in the given entity and any tracked principal entities related to it. つまり、他の場所での変更は、このメソッドの呼び出しで検出されなかった可能性があり、アプリケーション状態に影響する場合があります。This means that changes elsewhere may not have been detected by calling this method, which could have implications on application state.

ChangeTracker.AutoDetectChangesEnabledfalse に設定されている場合、このローカル変更の検出も無効になることに注意してください。Note that if ChangeTracker.AutoDetectChangesEnabled is set to false then even this local change detection will be disabled.

ChangeTracker.EntriesSaveChanges など、変更の検出の原因となる他のメソッドは引き続き、すべての追跡対象エンティティの完全な DetectChanges の原因となります。Other methods that cause change detection--for example ChangeTracker.Entries and SaveChanges--still cause a full DetectChanges of all tracked entities.

理由Why

この変更は、context.Entry を使用する既定のパフォーマンスを向上させるために行われました。This change was made to improve the default performance of using context.Entry.

軽減策Mitigations

3.0 より前の動作を確保するには、Entry を呼び出す前に明示的に ChangeTracker.DetectChanges() を呼び出します。Call ChangeTracker.DetectChanges() explicitly before calling Entry to ensure the pre-3.0 behavior.

文字列とバイト配列のキーが既定でクライアントによって生成されないString and byte array keys are not client-generated by default

問題 #14617 の追跡Tracking Issue #14617

以前の動作Old behavior

EF Core 3.0 より前では、stringbyte[] のキー プロパティは、null 以外の値を明示的に設定しなくても使用できました。Before EF Core 3.0, string and byte[] key properties could be used without explicitly setting a non-null value. このような場合、キーの値は GUID としてクライアントで生成され、byte[] のバイトにシリアル化されます。In such a case, the key value would be generated on the client as a GUID, serialized to bytes for byte[].

新しい動作New behavior

EF Core 3.0 以降では、キー値が設定されていないことを示す例外がスローされます。Starting with EF Core 3.0 an exception will be thrown indicating that no key value has been set.

理由Why

この変更は、クライアントで生成された string/byte[] 値が一般的に役に立たず、既定の動作では一般的な方法で生成されたキー値について判断するのが難しくなったため、行われました。This change was made because client-generated string/byte[] values generally aren't useful, and the default behavior made it hard to reason about generated key values in a common way.

軽減策Mitigations

3.0 より前の動作は、他の null 以外の値が設定されていない場合に、キー プロパティで生成された値を使用するように明示的に指定することで取得できます。The pre-3.0 behavior can be obtained by explicitly specifying that the key properties should use generated values if no other non-null value is set. たとえば、fluent API を使用する場合は、次のようになります。For example, with the fluent API:

modelBuilder
    .Entity<Blog>()
    .Property(e => e.Id)
    .ValueGeneratedOnAdd();

データ注釈を使用する場合は、次のようになります。Or with data annotations:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string Id { get; set; }

ILoggerFactory がスコープ サービスになったILoggerFactory is now a scoped service

問題 #14698 の追跡Tracking Issue #14698

以前の動作Old behavior

EF Core 3.0 より前では、ILoggerFactory はシングルトン サービスとして登録されました。Before EF Core 3.0, ILoggerFactory was registered as a singleton service.

新しい動作New behavior

EF Core 3.0 以降では、ILoggerFactory がスコープ化されたものとして登録されるようになりました。Starting with EF Core 3.0, ILoggerFactory is now registered as scoped.

理由Why

この変更は、DbContext インスタンスでのロガーの関連付けを許可し、他の機能を有効にし、内部サービス プロバイダーの急増などの異常な動作の一部のケースをなくすために行われました。This change was made to allow association of a logger with a DbContext instance, which enables other functionality and removes some cases of pathological behavior such as an explosion of internal service providers.

軽減策Mitigations

この変更は、EF Core の内部サービス プロバイダーでカスタム サービスを登録して使用しない限り、アプリケーション コードに影響しないはずです。This change should not impact application code unless it is registering and using custom services on the EF Core internal service provider. これは一般的ではありません。This isn't common. このような場合、ほとんどのものが引き続き機能しますが、ILoggerFactory に依存していたシングルトン サービスは、異なる方法で ILoggerFactory を取得するように変更する必要があります。In these cases, most things will still work, but any singleton service that was depending on ILoggerFactory will need to be changed to obtain the ILoggerFactory in a different way.

このような状況になった場合は、EF Core GitHub の問題追跡ツールで問題を提出し、ILoggerFactory の使用方法をお知らせください。これにより、Microsoft では、今後、再びこのように中断しない方法についてよりよく理解できます。If you run into situations like this, please file an issue at on the EF Core GitHub issue tracker to let us know how you are using ILoggerFactory such that we can better understand how not to break this again in the future.

遅延読み込みプロキシで、ナビゲーション プロパティが完全に読み込まれたと見なされなくなったLazy-loading proxies no longer assume navigation properties are fully loaded

問題 #12780 の追跡Tracking Issue #12780

以前の動作Old behavior

EF Core 3.0 より前では、DbContext が破棄されると、そのコンテキストから取得されたエンティティの特定のナビゲーション プロパティが完全に読み込まれたかどうかを知る方法はありませんでした。Before EF Core 3.0, once a DbContext was disposed there was no way of knowing if a given navigation property on an entity obtained from that context was fully loaded or not. プロキシでは、代わりに、null 以外の値がある場合は参照ナビゲーションが読み込まれ、空でない場合はコレクション ナビゲーションが読み込まれたと見なされます。Proxies would instead assume that a reference navigation is loaded if it has a non-null value, and that a collection navigation is loaded if it isn't empty. このような場合、遅延読み込みを試みても操作なしとなります。In these cases, attempting to lazy-load would be a no-op.

新しい動作New behavior

EF Core 3.0 以降では、プロキシで、ナビゲーション プロパティが読み込まれたかどうかの追跡が行われます。Starting with EF Core 3.0, proxies keep track of whether or not a navigation property is loaded. つまり、コンテキストが破棄された後に読み込まれたナビゲーション プロパティにアクセスしようとしても、通常は操作なしとなります。読み込まれたナビゲーションが空でも null であっても同様です。This means attempting to access a navigation property that is loaded after the context has been disposed will always be a no-op, even when the loaded navigation is empty or null. 逆に、コンテキストが破棄された場合、読み込まれなかったナビゲーション プロパティにアクセスしようとすると例外がスローされます。ナビゲーション プロパティが空ではないコレクションである場合でも同様です。Conversely, attempting to access a navigation property that isn't loaded will throw an exception if the context is disposed even if the navigation property is a non-empty collection. このような状況が発生した場合、アプリケーション コードで無効な時間に遅延読み込みの使用が試行されていることを意味し、アプリケーションを変更して、このようにならないようにする必要があります。If this situation arises, it means the application code is attempting to use lazy-loading at an invalid time, and the application should be changed to not do this.

理由Why

この変更は、破棄された DbContext インスタンスで遅延読み込みが試行されたときの動作を一貫した正しいものにするために行われました。This change was made to make the behavior consistent and correct when attempting to lazy-load on a disposed DbContext instance.

軽減策Mitigations

破棄されたコンテキストで遅延読み込みが試行されないようにアプリケーション コードを更新するか、例外メッセージの説明に従って、これを操作なしとなるように構成します。Update application code to not attempt lazy-loading with a disposed context, or configure this to be a no-op as described in the exception message.

内部サービス プロバイダーの過剰な作成が既定でエラーと見なされるようになったExcessive creation of internal service providers is now an error by default

問題 #10236 の追跡Tracking Issue #10236

以前の動作Old behavior

EF Core 3.0 より前では、異常な数の内部サービス プロバイダーを作成するアプリケーションに対する警告がログに記録されました。Before EF Core 3.0, a warning would be logged for an application creating a pathological number of internal service providers.

新しい動作New behavior

EF Core 3.0 以降では、この警告はエラーと見なされるようになり、例外がスローされます。Starting with EF Core 3.0, this warning is now considered and error and an exception is thrown.

理由Why

この変更は、この異常なケースをより明示的に示すことで、アプリケーション コードの改善を促進するために行われました。This change was made to drive better application code through exposing this pathological case more explicitly.

軽減策Mitigations

このエラーの発生時の最も適切なアクションは、根本原因を理解し、非常に多くの内部サービス プロバイダーを作成しないようにすることです。The most appropriate cause of action on encountering this error is to understand the root cause and stop creating so many internal service providers. しかし、DbContextOptionsBuilder での構成を使用して、エラーを警告に戻す (または無視する) ことがことができます。However, the error can be converted back to a warning (or ignored) via configuration on the DbContextOptionsBuilder. 次に例を示します。For example:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .ConfigureWarnings(w => w.Log(CoreEventId.ManyServiceProvidersCreatedWarning));
}

1 つの文字列と共に呼び出される HasOne/HasMany の新しい動作New behavior for HasOne/HasMany called with a single string

問題 #9171 の追跡Tracking Issue #9171

以前の動作Old behavior

EF Core 3.0 以前では、1 つの文字列と共に HasOne または HasMany が呼び出されるコードは、わかりにくい方法で解釈されていました。Before EF Core 3.0, code calling HasOne or HasMany with a single string was interpreted in a confusing way. 次に例を示します。For example:

modelBuilder.Entity<Samurai>().HasOne("Entrance").WithOne();

このコードは、プライベートである可能性がある Entrance ナビゲーション プロパティを使って、Samurai を他のエンティティ型に関連付けているように見えます。The code looks like it is relating Samurai to some other entity type using the Entrance navigation property, which may be private.

実際には、このコードは、ナビゲーション プロパティなしで、Entrance と呼ばれるエンティティ型に対してリレーションシップを作成しようとしています。In reality, this code attempts to create a relationship to some entity type called Entrance with no navigation property.

新しい動作New behavior

EF Core 3.0 以降では、上記のコードは、前にそれが実行すべきであるように見えたことを実行するようになりました。Starting with EF Core 3.0, the code above now does what it looked like it should have been doing before.

理由Why

以前の動作は、特に構成コードを読み取ってエラーを探す場合は、非常にわかりにくいものでした。The old behavior was very confusing, especially when reading the configuration code and looking for errors.

軽減策Mitigations

これが中断させるのは、型名の文字列を使って明示的にリレーションシップを構成し、かつ明示的にナビゲーション プロパティを指定しないアプリケーションのみです。This will only break applications that are explicitly configuring relationships using strings for type names and without specifying the navigation property explicitly. これは一般的ではありません。This is not common. 前の動作は、ナビゲーション プロパティ名に対して明示的に null を渡すことで実現できます。The previous behavior can be obtained through explicitly passing null for the navigation property name. 次に例を示します。For example:

modelBuilder.Entity<Samurai>().HasOne("Some.Entity.Type.Name", null).WithOne();

いくつかの非同期メソッドの戻り値の型が Task から ValueTask に変更されましたThe return type for several async methods has been changed from Task to ValueTask

問題 #15184 の追跡Tracking Issue #15184

以前の動作Old behavior

次の非同期メソッドでは、以前は Task<T> が返されていました。The following async methods previously returned a Task<T>:

  • DbContext.FindAsync()
  • DbSet.FindAsync()
  • DbContext.AddAsync()
  • DbSet.AddAsync()
  • ValueGenerator.NextValueAsync() (および派生クラス)ValueGenerator.NextValueAsync() (and deriving classes)

新しい動作New behavior

前述のメソッドは、以前と同じ T に対して ValueTask<T> を返すようになりました。The aforementioned methods now return a ValueTask<T> over the same T as before.

理由Why

この変更により、これらのメソッドを呼び出すときに発生するヒープ割り当ての数を削減して全般的なパフォーマンスを向上させます。This change reduces the number of heap allocations incurred when invoking these methods, improving general performance.

軽減策Mitigations

上記の API を待機しているだけのアプリケーションのみを再コンパイルする必要があります。ソースの変更は必要ありません。Applications simply awaiting the above APIs only need to be recompiled - no source changes are necessary. より複雑な使用方法 (返された TaskTask.WhenAny() に渡すなど) では通常、返された ValueTask<T>AsTask() を呼び出すことによって Task<T> に変換する必要があります。A more complex usage (e.g. passing the returned Task to Task.WhenAny()) typically require that the returned ValueTask<T> be converted to a Task<T> by calling AsTask() on it. これにより、この変更による割り当ての削減が無効になることに注意してください。Note that this negates the allocation reduction that this change brings.

Relational:TypeMapping 注釈が単に TypeMapping となったThe Relational:TypeMapping annotation is now just TypeMapping

問題 #9913 の追跡Tracking Issue #9913

以前の動作Old behavior

型マッピング注釈の注釈名は "Relational:TypeMapping" でした。The annotation name for type mapping annotations was "Relational:TypeMapping".

新しい動作New behavior

型マッピング注釈の注釈名は、"TypeMapping" となりました。The annotation name for type mapping annotations is now "TypeMapping".

理由Why

型マッピングが、リレーショナル データベース プロバイダー以外でも使用されるようになりました。Type mappings are now used for more than just relational database providers.

軽減策Mitigations

これにより、一般的ではない、注釈として直接型マッピングにアクセスするアプリケーションのみが中断されるようになります。This will only break applications that access the type mapping directly as an annotation, which isn't common. 問題を解決するための最も適切なアクションは、注釈を直接使用するのではなく、API サーフェスを使用して型マッピングにアクセスすることです。The most appropriate action to fix is to use API surface to access type mappings rather than using the annotation directly.

派生型の ToTable で例外がスローされるToTable on a derived type throws an exception

問題 #11811 の追跡Tracking Issue #11811

以前の動作Old behavior

EF Core 3.0 より前では、唯一の継承マッピング方法が TPH であり、これが有効でない場合には、派生型で呼び出された ToTable() が無視されていました。Before EF Core 3.0, ToTable() called on a derived type would be ignored since only inheritance mapping strategy was TPH where this isn't valid.

新しい動作New behavior

EF Core 3.0 以降、および今後のリリースでの TPT と TPC のサポートの追加準備中には、派生型で呼び出された ToTable() で、今後の予期されないマッピング変更を回避するために例外がスローされるようになります。Starting with EF Core 3.0 and in preparation for adding TPT and TPC support in a later release, ToTable() called on a derived type will now throw an exception to avoid an unexpected mapping change in the future.

理由Why

現在、派生型を別のテーブルにマップすることは有効ではありません。Currently it isn't valid to map a derived type to a different table. この変更により、今後、これを行うことが有効になった場合に中断されなくなります。This change avoids breaking in the future when it becomes a valid thing to do.

軽減策Mitigations

派生型を他のテーブルにマップしないようにします。Remove any attempts to map derived types to other tables.

ForSqlServerHasIndex が HasIndex に置き換えられたForSqlServerHasIndex replaced with HasIndex

問題 #12366 の追跡Tracking Issue #12366

以前の動作Old behavior

EF Core 3.0 より前では、ForSqlServerHasIndex().ForSqlServerInclude() によって、INCLUDE で使用される列を構成する方法が提供されました。Before EF Core 3.0, ForSqlServerHasIndex().ForSqlServerInclude() provided a way to configure columns used with INCLUDE.

新しい動作New behavior

EF Core 3.0 以降では、インデックスでの Include の使用が、リレーショナル レベルでサポートされるようになりました。Starting with EF Core 3.0, using Include on an index is now supported at the relational level. HasIndex().ForSqlServerInclude() を使用してください。Use HasIndex().ForSqlServerInclude().

理由Why

この変更は、すべてのデータ プロバイダーのために Include でインデックス用の API を 1 か所に統合するために行われました。This change was made to consolidate the API for indexes with Include into one place for all database providers.

軽減策Mitigations

上記のように、新しい API を使用します。Use the new API, as shown above.

メタデータ API の変更点Metadata API changes

問題 #214 の追跡Tracking Issue #214

新しい動作New behavior

次のプロパティは拡張メソッドに変換されました。The following properties were converted to extension methods:

  • IEntityType.QueryFilter -> GetQueryFilter()
  • IEntityType.DefiningQuery -> GetDefiningQuery()
  • IProperty.IsShadowProperty -> IsShadowProperty()
  • IProperty.BeforeSaveBehavior -> GetBeforeSaveBehavior()
  • IProperty.AfterSaveBehavior -> GetAfterSaveBehavior()

理由Why

この変更により、前述のインターフェイスの実装が簡単になります。This change simplifies the implementation of the aforementioned interfaces.

軽減策Mitigations

新しい拡張メソッドを使用します。Use the new extension methods.

プロバイダー固有のメタデータ API の変更Provider-specific Metadata API changes

問題 #214 の追跡Tracking Issue #214

新しい動作New behavior

プロバイダー固有の拡張メソッドがフラット化されます。The provider-specific extension methods will be flattened out:

  • IProperty.Relational().ColumnName -> IProperty.GetColumnName()
  • IEntityType.SqlServer().IsMemoryOptimized -> IEntityType.IsMemoryOptimized()
  • PropertyBuilder.UseSqlServerIdentityColumn() -> PropertyBuilder.UseIdentityColumn()

理由Why

この変更により、前述の拡張メソッドの実装が簡単になります。This change simplifies the implementation of the aforementioned extension methods.

軽減策Mitigations

新しい拡張メソッドを使用します。Use the new extension methods.

EF Core で SQLite FK を適用するためのプラグマが送信されなくなったEF Core no longer sends pragma for SQLite FK enforcement

問題 #12151 の追跡Tracking Issue #12151

以前の動作Old behavior

EF Core 3.0 より前では、EF Core で、SQLite への接続が開かれたときに PRAGMA foreign_keys = 1 が送信されました。Before EF Core 3.0, EF Core would send PRAGMA foreign_keys = 1 when a connection to SQLite is opened.

新しい動作New behavior

EF Core 3.0 以降では、EF Core で、SQLite への接続が開かれたときに PRAGMA foreign_keys = 1 が送信されなくなりました。Starting with EF Core 3.0, EF Core no longer sends PRAGMA foreign_keys = 1 when a connection to SQLite is opened.

理由Why

この変更は、既定で EF Core で SQLitePCLRaw.bundle_e_sqlite3 が使用され、その後、FK の適用が既定で有効になり、接続が開かれるたびに明示的に有効にする必要がないため、行われました。This change was made because EF Core uses SQLitePCLRaw.bundle_e_sqlite3 by default, which in turn means that FK enforcement is switched on by default and doesn't need to be explicitly enabled each time a connection is opened.

軽減策Mitigations

外部キーは、EF Core に対して既定で使用される、SQLitePCLRaw.bundle_e_sqlite3 で既定で有効になります。Foreign keys are enabled by default in SQLitePCLRaw.bundle_e_sqlite3, which is used by default for EF Core. それ以外の場合は、接続文字列で Foreign Keys=True を指定することで、外部キーを有効にできます。For other cases, foreign keys can be enabled by specifying Foreign Keys=True in your connection string.

Microsoft.EntityFrameworkCore.Sqlite が SQLitePCLRaw.bundle_e_sqlite3 に依存するようになったMicrosoft.EntityFrameworkCore.Sqlite now depends on SQLitePCLRaw.bundle_e_sqlite3

以前の動作Old behavior

EF Core 3.0 より前では、EF Core では SQLitePCLRaw.bundle_green が使用されていました。Before EF Core 3.0, EF Core used SQLitePCLRaw.bundle_green.

新しい動作New behavior

EF Core 3.0 以降では、EF Core で SQLitePCLRaw.bundle_e_sqlite3 が使用されます。Starting with EF Core 3.0, EF Core uses SQLitePCLRaw.bundle_e_sqlite3.

理由Why

この変更は、iOS 上で使用される SQLite のバージョンを、他のプラットフォームと一致させるために行われました。This change was made so that the version of SQLite used on iOS consistent with other platforms.

軽減策Mitigations

iOS でネイティブの SQLite バージョンを使用するには、別の SQLitePCLRaw バンドルを使用するように Microsoft.Data.Sqlite を構成します。To use the native SQLite version on iOS, configure Microsoft.Data.Sqlite to use a different SQLitePCLRaw bundle.

GUID の値が SQLite にテキストとして格納されるようになったGuid values are now stored as TEXT on SQLite

問題 #15078 の追跡Tracking Issue #15078

以前の動作Old behavior

GUID の値は、以前は SQLite に BLOB 値として格納されていました。Guid values were previously stored as BLOB values on SQLite.

新しい動作New behavior

GUID の値はテキストとして格納されるようになりました。Guid values are now stored as TEXT.

理由Why

GUID のバイナリ形式は標準化されていません。The binary format of Guids is not standardized. 値をテキストとして格納する方が、データベースと他のテクノロジとの互換性が高まるためです。Storing the values as TEXT makes the database more compatible with other technologies.

軽減策Mitigations

次のように SQL を実行すると、既存のデータベースを新しい形式に移行することができます。You can migrate existing databases to the new format by executing SQL like the following.

UPDATE MyTable
SET GuidColumn = hex(substr(GuidColumn, 4, 1)) ||
                 hex(substr(GuidColumn, 3, 1)) ||
                 hex(substr(GuidColumn, 2, 1)) ||
                 hex(substr(GuidColumn, 1, 1)) || '-' ||
                 hex(substr(GuidColumn, 6, 1)) ||
                 hex(substr(GuidColumn, 5, 1)) || '-' ||
                 hex(substr(GuidColumn, 8, 1)) ||
                 hex(substr(GuidColumn, 7, 1)) || '-' ||
                 hex(substr(GuidColumn, 9, 2)) || '-' ||
                 hex(substr(GuidColumn, 11, 6))
WHERE typeof(GuidColumn) == 'blob';

EF Core では、このようなプロパティで値コンバーターを構成することで、以前の動作を使い続けることもできます。In EF Core, you could also continue using the previous behavior by configuring a value converter on these properties.

modelBuilder
    .Entity<MyEntity>()
    .Property(e => e.GuidProperty)
    .HasConversion(
        g => g.ToByteArray(),
        b => new Guid(b));

Microsoft.Data.Sqlite は引き続き、BLOB とテキストの両方の列から GUID 値を読み取ることができます。ただし、パラメーターと定数の既定の形式が変更されているため、GUID が含まれる多くのシナリオではアクションが必要になります。Microsoft.Data.Sqlite remains capable of reading Guid values from both BLOB and TEXT columns; however, since the default format for parameters and constants has changed you'll likely need to take action for most scenarios involving Guids.

Char の値が SQLite にテキストとして格納されるようになったChar values are now stored as TEXT on SQLite

問題 #15020 の追跡Tracking Issue #15020

以前の動作Old behavior

Char の値は、以前は SQLite に整数値として格納されていました。Char values were previously sored as INTEGER values on SQLite. たとえば、Char の値 A は整数値 65 として格納されていました。For example, a char value of A was stored as the integer value 65.

新しい動作New behavior

Char の値はテキストとして格納されるようになりました。Char values are now stored as TEXT.

理由Why

値をテキストとして格納する方が自然であり、データベースと他のテクノロジとの互換性が高まるためです。Storing the values as TEXT is more natural and makes the database more compatible with other technologies.

軽減策Mitigations

次のように SQL を実行すると、既存のデータベースを新しい形式に移行することができます。You can migrate existing databases to the new format by executing SQL like the following.

UPDATE MyTable
SET CharColumn = char(CharColumn)
WHERE typeof(CharColumn) = 'integer';

EF Core では、このようなプロパティで値コンバーターを構成することで、以前の動作を使い続けることもできます。In EF Core, you could also continue using the previous behavior by configuring a value converter on these properties.

modelBuilder
    .Entity<MyEntity>()
    .Property(e => e.CharProperty)
    .HasConversion(
        c => (long)c,
        i => (char)i);

Microsoft.Data.Sqlite では、引き続き整数とテキストの両方の列の文字列値を読み取ることができるため、一部のシナリオではアクションが必要ありません。Microsoft.Data.Sqlite also remains capable of reading character values from both INTEGER and TEXT columns, so certain scenarios may not require any action.

移行 ID がインバリアント カルチャの暦を使用して生成されるようになったMigration IDs are now generated using the invariant culture's calendar

問題 #12978 の追跡Tracking Issue #12978

以前の動作Old behavior

移行 ID は、誤って現在のカルチャの暦を使用して生成されていました。Migration IDs were inadvertently generated using the current culture's calendar.

新しい動作New behavior

移行 ID がインバリアント カルチャの暦 (グレゴリオ暦) を使用して常に生成されるようになりました。Migration IDs are now always generated using the invariant culture's calendar (Gregorian).

理由Why

データベースを更新するときやマージの競合を解決するときに、移行の順序は重要です。The order of migrations is important when updating the database or resolving merge conflicts. インバリアントの暦を使用することで、順序の問題が回避され、システムの予定表がチームのメンバーごとに違うことがなくなります。Using the invariant calendar avoids ordering issues that can result from team members having different system calendars.

軽減策Mitigations

この変更は、1 年がグレゴリオ暦より長くなるグレゴリオ暦以外の暦 (タイ仏暦など) を使用しているすべてのユーザーに影響します。This change affects anyone using a non-Gregorian calendar where the year is greater than the Gregorian calendar (like the Thai Buddhist calendar). 既存の移行後に新しい移行順序が設定されるように、既存の移行 ID を更新する必要があります。Existing migration IDs will need to be updated so that new migrations are ordered after existing migrations.

移行 ID は、移行のデザイナー ファイルの移行属性にあります。The migration ID can be found in the Migration attribute in the migrations' designer files.

 [DbContext(typeof(MyDbContext))]
-[Migration("25620318122820_MyMigration")]
+[Migration("20190318122820_MyMigration")]
 partial class MyMigration
 {

移行履歴テーブルも更新する必要があります。The Migrations history table also needs to be updated.

UPDATE __EFMigrationsHistory
SET MigrationId = CONCAT(LEFT(MigrationId, 4)  - 543, SUBSTRING(MigrationId, 4, 150))

UseRowNumberForPaging の削除UseRowNumberForPaging has been removed

問題 #16400 の追跡Tracking Issue #16400

以前の動作Old behavior

EF Core 3.0 より前では、UseRowNumberForPaging を使って、SQL Server 2008 と互換性のあるページング用の SQL を生成することができました。Before EF Core 3.0, UseRowNumberForPaging could be used to generate SQL for paging that is compatible with SQL Server 2008.

新しい動作New behavior

EF Core 3.0 以降では、EF によって生成できるのは、それ以降のバージョンの SQL Server とのみ互換性があるページング用の SQL のみとなります。Starting with EF Core 3.0, EF will only generate SQL for paging that is only compatible with later SQL Server versions.

理由Why

SQL Server 2008 はもうサポートされていない製品であり、EF Core 3.0 で行われたクエリの変更に対応するようこの機能を更新する作業は負荷が大きいため、このような変更が行われます。We are making this change because SQL Server 2008 is no longer a supported product and updating this feature to work with the query changes made in EF Core 3.0 is significant work.

軽減策Mitigations

生成された SQL がサポートされるように、より新しいバージョンの SQL Server に更新するか、より高い互換性レベルを使用することをお勧めします。We recommend updating to a newer version of SQL Server, or using a higher compatibility level, so that the generated SQL is supported. ただし、これを実行できない場合は、詳細情報とともに問題の追跡にコメントしてください。That being said, if you are unable to do this, then please comment on the tracking issue with details. Microsoft では、フィードバックに基づいてこの決定を再検討する場合があります。We may revisit this decision based on feedback.

IDbContextOptionsExtension から拡張機能の情報/メタデータを削除Extension info/metadata has been removed from IDbContextOptionsExtension

問題 #16119 の追跡Tracking Issue #16119

以前の動作Old behavior

IDbContextOptionsExtension には、拡張機能に関するメタデータを提供するためのメソッドが含まれていました。IDbContextOptionsExtension contained methods for providing metadata about the extension.

新しい動作New behavior

これらのメソッドは、新しい抽象基底クラス DbContextOptionsExtensionInfo 上に移動されました。これは新しい IDbContextOptionsExtension.Info プロパティから返されます。These methods have been moved onto a new DbContextOptionsExtensionInfo abstract base class, which is returned from a new IDbContextOptionsExtension.Info property.

理由Why

2.0 から 3.0 までのリリースを通して、これらのメソッドに追加または変更を行う必要が複数回発生しました。Over the releases from 2.0 to 3.0 we needed to add to or change these methods several times. それらを抜き出して新しい抽象基底クラスに含めることで、既存の拡張機能を損なうことなく、簡単にこのような変更を加えられるようになります。Breaking them out into a new abstract base class will make it easier to make these kind of changes without breaking existing extensions.

軽減策Mitigations

新しいパターンに従うよう拡張機能を更新します。Update extensions to follow the new pattern. その例は、EF Core のソース コードの、さまざまな種類の拡張機能に対する多数の IDbContextOptionsExtension の実装で見つかります。Examples are found in the many implementations of IDbContextOptionsExtension for different kinds of extensions in the EF Core source code.

LogQueryPossibleExceptionWithAggregateOperator の名前が変更されたLogQueryPossibleExceptionWithAggregateOperator has been renamed

問題 #10985 の追跡Tracking Issue #10985

変更Change

RelationalEventId.LogQueryPossibleExceptionWithAggregateOperator の名前が RelationalEventId.LogQueryPossibleExceptionWithAggregateOperatorWarning に変更されました。RelationalEventId.LogQueryPossibleExceptionWithAggregateOperator has been renamed to RelationalEventId.LogQueryPossibleExceptionWithAggregateOperatorWarning.

理由Why

この警告イベントの名前が他のすべての警告イベントと照合されるためです。Aligns the naming of this warning event with all other warning events.

軽減策Mitigations

新しい名前を使用します。Use the new name. (イベント ID 番号が変更されていないことを確認してください。)(Note that the event ID number has not changed.)

外部キー制約名の API が明確化されたClarify API for foreign key constraint names

問題 #10730 の追跡Tracking Issue #10730

以前の動作Old behavior

EF Core 3.0 以前は、外部キー制約名が単に "名前" と呼ばれていました。Before EF Core 3.0, foreign key constraint names were referred to as simply the "name". 次に例を示します。For example:

var constraintName = myForeignKey.Name;

新しい動作New behavior

EF Core 3.0 以降は、外部キー制約名が "制約名" と呼ばれるようになりました。Starting with EF Core 3.0, foreign key constraint names are now referred to as the "constraint name". 次に例を示します。For example:

var constraintName = myForeignKey.ConstraintName;

理由Why

この変更により、この領域の名前付けに一貫性がもたらされます。また、それが外部キーが定義されている列やプロパティの名前ではなく、外部キー制約の名前であることが明確になりました。This change brings consistency to naming in this area, and also clarifies that this is the name of the foreign key constraint, and not the column or property name that the foreign key is defined on.

軽減策Mitigations

新しい名前を使用します。Use the new name.

IRelationalDatabaseCreator.HasTables/HasTablesAsync をパブリックに変更IRelationalDatabaseCreator.HasTables/HasTablesAsync have been made public

問題 #15997 の追跡Tracking Issue #15997

以前の動作Old behavior

EF Core 3.0 より前では、これらのメソッドは保護されていました。Before EF Core 3.0, these methods were protected.

新しい動作New behavior

EF Core 3.0 以降、これらのメソッドはパブリックになります。Starting with EF Core 3.0, these methods are public.

理由Why

これらのメソッドは、作成されたデータベースが空であるかどうかを判断するために EF によって使用されます。These methods are used by EF to determine if a database is created but empty. これは、EF の外部から、移行を適用するかどうか判断する場合にも役立ちます。This can also be useful from outside EF when determining whether or not to apply migrations.

軽減策Mitigations

すべてのオーバーライドのアクセシビリティを変更します。Change the accessibility of any overrides.

Microsoft.EntityFrameworkCore.Design を DevelopmentDependency パッケージに変更Microsoft.EntityFrameworkCore.Design is now a DevelopmentDependency package

問題 #11506 の追跡Tracking Issue #11506

以前の動作Old behavior

EF Core 3.0 より前では、Microsoft.EntityFrameworkCore.Design は通常の NuGet パッケージであり、それに依存していたプロジェクトによってそのアセンブリを参照できました。Before EF Core 3.0, Microsoft.EntityFrameworkCore.Design was a regular NuGet package whose assembly could be referenced by projects that depended on it.

新しい動作New behavior

EF Core 3.0 以降、これは DevelopmentDependency パッケージになります。Starting with EF Core 3.0, it is a DevelopmentDependency package. つまり、依存関係が他のプロジェクトに推移的にフローすることがなくなり、規定ではそのアセンブリを参照できなくなります。This means that the dependency won't flow transitively into other projects, and that you can no longer, by default, reference its assembly.

理由Why

このパッケージは、デザイン時に使用されることだけを想定しています。This package is only intended to be used at design time. デプロイされたアプリケーションからこれを参照すべきではありません。Deployed applications shouldn't reference it. パッケージを DevelopmentDependency にすることで、この推奨事項が強化されます。Making the package a DevelopmentDependency reinforces this recommendation.

軽減策Mitigations

EF Core のデザイン時の動作をオーバーライドするためにこのパッケージを参照する必要がある場合は、プロジェクトの PackageReference 項目メタデータを更新することができます。If you need to reference this package to override EF Core's design-time behavior, then you can update PackageReference item metadata in your project.

<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0">
  <PrivateAssets>all</PrivateAssets>
  <!-- Remove IncludeAssets to allow compiling against the assembly -->
  <!--<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>-->
</PackageReference>

このパッケージが Microsoft.EntityFrameworkCore.Tools 経由で推移的に参照されている場合は、パッケージに明示的な PackageReference を追加して、そのメタデータを変更する必要があります。If the package is being referenced transitively via Microsoft.EntityFrameworkCore.Tools, you will need to add an explicit PackageReference to the package to change its metadata. このような明示的な参照は、パッケージの型が必要なプロジェクトに追加する必要があります。Such an explicit reference must be added to any project where the types from the package are needed.

SQLitePCL.raw のバージョン 2.0.0 への更新SQLitePCL.raw updated to version 2.0.0

問題 #14824 の追跡Tracking Issue #14824

以前の動作Old behavior

Microsoft.EntityFrameworkCore.Sqlite は、以前はバージョン 1.1.12 の SQLitePCL.raw に依存していました。Microsoft.EntityFrameworkCore.Sqlite previously depended on version 1.1.12 of SQLitePCL.raw.

新しい動作New behavior

バージョン 2.0.0 に依存するようパッケージが更新されました。We've updated our package to depend on version 2.0.0.

理由Why

バージョン 2.0.0 の SQLitePCL.raw では、.NET Standard 2.0 をターゲットとします。Version 2.0.0 of SQLitePCL.raw targets .NET Standard 2.0. これは以前は、推移的なパッケージの大規模なクロージャの動作を必要とする .NET Standard 1.1 をターゲットとしていました。It previously targeted .NET Standard 1.1 which required a large closure of transitive packages to work.

軽減策Mitigations

SQLitePCL.raw バージョン 2.0.0 には、いくつかの破壊的変更が含まれています。SQLitePCL.raw version 2.0.0 includes some breaking changes. 詳細については、リリース ノートをご覧ください。See the release notes for details.

NetTopologySuite のバージョン 2.0.0 への更新NetTopologySuite updated to version 2.0.0

問題 #14825 の追跡Tracking Issue #14825

以前の動作Old behavior

以前の空間パッケージはバージョン 1.15.1 の NetTopologySuite に依存していました。The spatial packages previously depended on version 1.15.1 of NetTopologySuite.

新しい動作New behavior

バージョン 2.0.0 に依存するようパッケージが更新されました。We've update our package to depend on version 2.0.0.

理由Why

バージョン 2.0.0 の NetTopologySuite は、EF Core の使用に伴ういくつかのユーザビリティの問題に対処することを目的としています。Version 2.0.0 of NetTopologySuite aims to address several usability issues encountered by EF Core users.

軽減策Mitigations

NetTopologySuite バージョン 2.0.0 には、いくつかの破壊的変更が含まれています。NetTopologySuite version 2.0.0 includes some breaking changes. 詳細については、リリース ノートをご覧ください。See the release notes for details.

System.Data.SqlClient ではなく Microsoft.Data.SqlClient が使用されるMicrosoft.Data.SqlClient is used instead of System.Data.SqlClient

問題 #15636 の追跡Tracking Issue #15636

以前の動作Old behavior

Microsoft.EntityFrameworkCore.SqlServer は、以前は System.Data.SqlClient に依存していました。Microsoft.EntityFrameworkCore.SqlServer previously depended on System.Data.SqlClient.

新しい動作New behavior

Microsoft.Data.SqlClient に依存するようにパッケージを更新しました。We've updated our package to depend on Microsoft.Data.SqlClient.

理由Why

Microsoft.Data.SqlClient は今後の SQL Server の主力データ アクセス ドライバーであり、System.Data.SqlClient は開発の中心ではなくなりました。Microsoft.Data.SqlClient is the flagship data access driver for SQL Server going forward, and System.Data.SqlClient no longer be the focus of development. Always Encrypted などの重要な機能は、Microsoft.Data.SqlClient でのみ使用できます。Some important features, such as Always Encrypted, are only available on Microsoft.Data.SqlClient.

軽減策Mitigations

コードが System.Data.SqlClient に直接依存している場合は、代わりに Microsoft.Data.SqlClient を参照するように変更する必要があります。2 つのパッケージは非常に高度な API 互換性を維持しているため、これは単純なパッケージと名前空間の変更のみである必要があります。If your code takes a direct dependency on System.Data.SqlClient, you must change it to reference Microsoft.Data.SqlClient instead; as the two packages maintain a very high degree of API compatibility, this should only be a simple package and namespace change.

複数のあいまいな自己参照リレーションシップを構成する必要があるMultiple ambiguous self-referencing relationships must be configured

イシュー #13573 の追跡Tracking Issue #13573

以前の動作Old behavior

複数の自己参照型一方向ナビゲーション プロパティと一致する FK を持つエンティティ型が、1 つのリレーションシップとして正しく構成されませんでした。An entity type with multiple self-referencing uni-directional navigation properties and matching FKs was incorrectly configured as a single relationship. 次に例を示します。For example:

public class User 
{
        public Guid Id { get; set; }
        public User CreatedBy { get; set; }
        public User UpdatedBy { get; set; }
        public Guid CreatedById { get; set; }
        public Guid? UpdatedById { get; set; }
}

新しい動作New behavior

このシナリオがモデル構築で検出されるようになり、モデルがあいまいであることを示す例外がスローされます。This scenario is now detected in model building and an exception is thrown indicating that the model is ambiguous.

理由Why

結果として得られるモデルはあいまいであり、通常、この場合には間違っている可能性があるためです。The resultant model was ambiguous and will likely usually be wrong for this case.

軽減策Mitigations

完全に構成されたリレーションシップを使用します。Use full configuration of the relationship. 次に例を示します。For example:

modelBuilder
     .Entity<User>()
     .HasOne(e => e.CreatedBy)
     .WithMany();
 
 modelBuilder
     .Entity<User>()
     .HasOne(e => e.UpdatedBy)
     .WithMany();

DbFunction.Schema が null または空の文字列である場合、モデルの既定のスキーマに構成されるDbFunction.Schema being null or empty string configures it to be in model's default schema

問題 #12757 の追跡Tracking Issue #12757

以前の動作Old behavior

空の文字列としてスキーマを使用して構成された DbFunction は、スキーマのない組み込み関数として扱われていました。A DbFunction configured with schema as an empty string was treated as built-in function without a schema. たとえば、次のコードは DatePart CLR 関数を SqlServer の組み込み関数 DATEPART にマップします。For example following code will map DatePart CLR function to DATEPART built-in function on SqlServer.

[DbFunction("DATEPART", Schema = "")]
public static int? DatePart(string datePartArg, DateTime? date) => throw new Exception();

新しい動作New behavior

すべての DbFunction マッピングは、ユーザー定義関数にマップされるものと見なされます。All DbFunction mappings are considered to be mapped to user defined functions. そのため、空の文字列値を指定すると、関数がモデルの既定のスキーマ内に配置されます。Hence empty string value would put the function inside the default schema for the model. それ以外の、スキーマとなり得るものは fluent API の modelBuilder.HasDefaultSchema() または dbo を使用して明示的に構成されます。Which could be the schema configured explicitly via fluent API modelBuilder.HasDefaultSchema() or dbo otherwise.

理由Why

以前は空のスキーマを使用して関数を組み込みとして扱っていましたが、そのロジックは、組み込みの関数がどのスキーマにも属していない SqlServer にのみ適用されます。Previously schema being empty was a way to treat that function is built-in but that logic is only applicable for SqlServer where built-in functions do not belong to any schema.

軽減策Mitigations

DbFunction の変換を手動で組み込み関数にマップされるように構成します。Configure DbFunction's translation manually to map it to a built-in function.

modelBuilder
    .HasDbFunction(typeof(MyContext).GetMethod(nameof(MyContext.DatePart)))
    .HasTranslation(args => SqlFunctionExpression.Create("DatePart", args, typeof(int?), null));