從 EF6 移植至 EF CorePorting from EF6 to EF Core

因為 EF Core 在本質上有所變更,我們不建議嘗試將 EF6 應用程式移至 EF Core,除非您有充足的理由進行該變更。Because of the fundamental changes in EF Core we do not recommend attempting to move an EF6 application to EF Core unless you have a compelling reason to make the change. 您應該將從 EF6 移至 EF Core 視為移植,而非升級。You should view the move from EF6 to EF Core as a port rather than an upgrade.

重要

在開始移植程序之前,請務必確認 EF Core 符合應用程式的資料存取需求。Before you start the porting process it is important to validate that EF Core meets the data access requirements for your application.

遺漏的功能Missing features

請確定 EF Core 具有應用程式中所需的所有功能。Make sure that EF Core has all the features you need to use in your application. 如需 EF Core 中的功能集與 EF6 相比的詳細比較,請參閱功能比較See Feature Comparison for a detailed comparison of how the feature set in EF Core compares to EF6. 如果遺漏任何必要的功能,請確保在移植到 EF Core 之前可以彌補這些功能的不足。If any required features are missing, ensure that you can compensate for the lack of these features before porting to EF Core.

行為變更Behavior changes

這是 EF6 和 EF Core 之間一些行為變更的不完整清單。This is a non-exhaustive list of some changes in behavior between EF6 and EF Core. 在移植應用程式時,請務必牢記這些問題,因為它們可能會變更應用程式的行為方式,但在切換到 EF Core 之後,不會顯示為編譯錯誤。It is important to keep these in mind as your port your application as they may change the way your application behaves, but will not show up as compilation errors after swapping to EF Core.

DbSet.Add/附加和圖形行為DbSet.Add/Attach and graph behavior

在 EF6 中,在實體上呼叫 DbSet.Add() 會導致以遞迴方式搜尋其導覽屬性中參考的所有實體。In EF6, calling DbSet.Add() on an entity results in a recursive search for all entities referenced in its navigation properties. 任何找到的實體 (而且尚未執行內容追蹤),也會標示為已加入。Any entities that are found, and are not already tracked by the context, are also marked as added. DbSet.Attach() 行為相同,不同之處在於所有實體都會標示為未變更。DbSet.Attach() behaves the same, except all entities are marked as unchanged.

EF Core 會執行類似的遞迴搜尋,但有一些略有不同的規則。EF Core performs a similar recursive search, but with some slightly different rules.

  • 根實體一律處於要求的狀態 (針對 DbSet.Add 進行新增,針對 DbSet.Attach 則未變更)。The root entity is always in the requested state (added for DbSet.Add and unchanged for DbSet.Attach).
  • 針對在遞迴搜尋導覽屬性期間找到的實體:For entities that are found during the recursive search of navigation properties:
    • 如果實體的主索引鍵是存放區產生的If the primary key of the entity is store generated
      • 如果主索引鍵未設定為值,則狀態會設定為「已加入」。If the primary key is not set to a value, the state is set to added. 如果為主索引鍵指派了屬性類型的 CLR 預設值 (例如,0 代表 intnull 代表 string 等),則會將它視為「未設定」。The primary key value is considered "not set" if it is assigned the CLR default value for the property type (for example, 0 for int, null for string, etc.).
      • 如果主索引鍵設定為值,則狀態會設定為「未變更」。If the primary key is set to a value, the state is set to unchanged.
    • 如果主索引鍵不是資料庫產生的,實體會置於與根相同的狀態。If the primary key is not database generated, the entity is put in the same state as the root.

Code First 資料庫初始化Code First database initialization

EF6 在選取資料庫連接和初始化資料庫方面,有非常神奇之處。其中一些規則包括:EF6 has a significant amount of magic it performs around selecting the database connection and initializing the database. Some of these rules include:

  • 如果沒有執行任何設定,EF6 將在 SQL Express 或 LocalDb 上選取一個資料庫。If no configuration is performed, EF6 will select a database on SQL Express or LocalDb.

  • 如果與執行內容同名的連接字串位於應用程式 App/Web.config 檔案中,則會使用此連線。If a connection string with the same name as the context is in the applications App/Web.config file, this connection will be used.

  • 如果資料庫不存在,則會建立資料庫。If the database does not exist, it is created.

  • 如果模型中沒有任何資料表存在於資料庫中,則會將目前模型的結構描述新增至資料庫。If none of the tables from the model exist in the database, the schema for the current model is added to the database. 如果已啟用移轉,則會使用它們來建立資料庫。If migrations are enabled, then they are used to create the database.

  • 如果資料庫存在,而且 EF6 先前已建立結構描述,則會檢查結構描述是否與目前的模型相容。If the database exists and EF6 had previously created the schema, then the schema is checked for compatibility with the current model. 如果模型在建立結構描述之後已變更,就會擲回例外狀況。An exception is thrown if the model has changed since the schema was created.

EF Core 無法執行任何此類操作。EF Core does not perform any of this magic.

  • 資料庫連接必須在程式碼中明確設定。The database connection must be explicitly configured in code.

  • 不會執行任何初始化。No initialization is performed. 您必須使用 DbContext.Database.Migrate() 來套用移轉 (或 DbContext.Database.EnsureCreated()EnsureDeleted(),以建立/刪除資料庫,而不使用移轉)。You must use DbContext.Database.Migrate() to apply migrations (or DbContext.Database.EnsureCreated() and EnsureDeleted() to create/delete the database without using migrations).

Code First 資料表命名慣例Code First table naming convention

EF6 會透過複數服務執行實體類別名稱,以計算實體所對應的預設資料表名稱。EF6 runs the entity class name through a pluralization service to calculate the default table name that the entity is mapped to.

EF Core 會使用在衍生內容上公開實體的 DbSet 屬性名稱。EF Core uses the name of the DbSet property that the entity is exposed in on the derived context. 如果實體沒有 DbSet 屬性,則會使用類別名稱。If the entity does not have a DbSet property, then the class name is used.