EF6 與 EF Core 之間的行為變更

這是 EF6 與 EF Core 之間行為變更的非詳盡清單。 在移植應用程式時,請務必牢記這些問題,因為它們可能會變更應用程式的行為方式,但在切換到 EF Core 之後,不會顯示為編譯錯誤。

這表示要作為移植程式一部分的高層級檢閱。 如需更詳細的逐案例指示,請閱讀 詳細案例

DbSet.Add/附加和圖形行為

在 EF6 中,在實體上呼叫 DbSet.Add() 會導致以遞迴方式搜尋其導覽屬性中參考的所有實體。 任何找到的實體 (而且尚未執行內容追蹤),也會標示為已加入。 DbSet.Attach() 行為相同,不同之處在於所有實體都會標示為未變更。

EF Core 會執行類似的遞迴搜尋,但有一些略有不同的規則。

  • 如果根實體已針對產生的索引鍵進行設定,且未設定索引鍵,則會進入 Added 狀態。
  • 針對在遞迴搜尋導覽屬性期間找到的實體:
    • 如果實體的主索引鍵是存放區產生的
      • 如果主索引鍵未設定為值,則狀態會設定為「已加入」。 如果為主索引鍵指派了屬性類型的 CLR 預設值 (例如,0 代表 intnull 代表 string 等),則會將它視為「未設定」。
      • 如果主索引鍵設定為值,則狀態會設定為「未變更」。
    • 如果主索引鍵不是資料庫產生的,實體會置於與根相同的狀態。
  • 此行為變更僅適用于 AttachUpdate 方法群組。 Add 一律會將實體 Added 置於狀態,即使已設定索引鍵也一樣。
  • Attach 方法會將已設定索引鍵的 Unchanged 實體放入狀態。 這有助於「如果新增,則插入它,否則將它單獨插入」。 Update 方法會將已設定索引鍵的 Modified 實體放入狀態。 這有助於「如果新增,則插入它,否則更新它」。

這裡的一般哲學是 Update 處理中斷連線實體插入和更新的非常簡單方式。 它可確保插入任何新的實體,並更新任何現有的實體。

同時, Add 仍然提供簡單的強制實體插入方式。 只有在不使用預存產生的金鑰時,新增最有用,因此 EF 不知道實體是否為新的。

如需 EF Core 中這些行為的詳細資訊,請參閱 EF Core 中的變更追蹤。

Code First 資料庫初始化

EF6 在選取資料庫連接和初始化資料庫方面,有非常神奇之處。 其中一些規則包括:

  • 如果沒有執行任何設定,EF6 將在 SQL Express 或 LocalDb 上選取一個資料庫。
  • 如果與內容同名的連接字串位於應用程式的 App/Web.config 檔案中,將會使用此連線。
  • 如果資料庫不存在,則會建立資料庫。
  • 如果模型中沒有任何資料表存在於資料庫中,則會將目前模型的結構描述新增至資料庫。 如果已啟用移轉,則會使用它們來建立資料庫。
  • 如果資料庫存在,而且 EF6 先前已建立結構描述,則會檢查結構描述是否與目前的模型相容。 如果模型在建立結構描述之後已變更,就會擲回例外狀況。

EF Core 無法執行任何此類操作。

  • 資料庫連接必須在程式碼中明確設定。
  • 不會執行任何初始化。 您必須使用 DbContext.Database.Migrate() 來套用移轉 (或 DbContext.Database.EnsureCreated()EnsureDeleted(),以建立/刪除資料庫,而不使用移轉)。

Code First 資料表命名慣例

EF6 會透過複數服務執行實體類別名稱,以計算實體所對應的預設資料表名稱。

EF Core 會使用在衍生內容上公開實體的 DbSet 屬性名稱。 如果實體沒有 DbSet 屬性,則會使用類別名稱。

如需詳細資訊,請參閱 管理資料庫架構