建立和設定模型
EF Core 會使用中繼資料 模型 來描述應用程式的實體類型如何對應至基礎資料庫。 此模型是使用一組 慣例 來建置的 - 啟發學習法,以尋找常見的模式。 然後,您可以使用中的對應屬性(也稱為 資料批註 ) 和/或呼叫 ModelBuilder 方法 (也稱為 Fluent API ) OnModelCreating 來自訂 模型,這兩者都會覆寫慣例所執行的組態。
大部分的組態都可以套用至以任何資料存放區為目標的模型。 提供者也可以啟用特定資料存放區特定的設定,也可以忽略不支援或不適用的設定。 如需提供者特定設定的檔,請參閱 資料庫提供者 一節。
提示
您可以在 GitHub 上檢視本文的 範例 。
使用 Fluent API 設定模型
您可以在衍生內容中覆寫 OnModelCreating
方法,並使用 Fluent API 來設定模型。 這是最強大的組態方法,讓您能夠指定組態而不修改實體類別。 Fluent API 組態具有最高的優先順序,且會覆寫慣例及資料註解。 系統會依呼叫方法的順序套用組態,如果發生任何衝突,最新的呼叫將會覆寫先前指定的組態。
using Microsoft.EntityFrameworkCore;
namespace EFModeling.EntityProperties.FluentAPI.Required;
internal class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
#region Required
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Url)
.IsRequired();
}
#endregion
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
提示
若要將相同的組態套用至模型中的多個物件,請參閱 大量設定 。
群組設定
若要減少 OnModelCreating
方法的大小,實體類型的所有設定可以另行擷取至實作 IEntityTypeConfiguration<TEntity> 的類別。
public class BlogEntityTypeConfiguration : IEntityTypeConfiguration<Blog>
{
public void Configure(EntityTypeBuilder<Blog> builder)
{
builder
.Property(b => b.Url)
.IsRequired();
}
}
然後,只要從 OnModelCreating
叫用 Configure
方法即可。
new BlogEntityTypeConfiguration().Configure(modelBuilder.Entity<Blog>());
套用元件中的所有組態
您可以套用在指定組件中實作 IEntityTypeConfiguration
的類型中所指定的所有設定。
modelBuilder.ApplyConfigurationsFromAssembly(typeof(BlogEntityTypeConfiguration).Assembly);
注意
因為我們未定義設定的套用順序,建議只有在順序不重要時,才使用此方法。
在 EntityTypeConfigurationAttribute
實體類型上使用
而不是明確呼叫 Configure
, EntityTypeConfigurationAttribute 可以改為放在實體類型上,讓 EF Core 能夠尋找及使用適當的組態。 例如:
[EntityTypeConfiguration(typeof(BookConfiguration))]
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public string Isbn { get; set; }
}
這個屬性工作表示每當模型中包含實體類型時, Book
EF Core 都會使用指定的 IEntityTypeConfiguration
實作。 實體類型會使用其中一個一般機制包含在模型中。 例如,藉由建立 DbSet<TEntity> 實體類型的 屬性:
public class BooksContext : DbContext
{
public DbSet<Book> Books { get; set; }
//...
或者,在 中 OnModelCreating 註冊它:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Book>();
}
注意
EntityTypeConfigurationAttribute
不會在元件中自動探索類型。 實體類型必須先新增至模型,才能在該實體類型上探索屬性。
使用資料註解
您也可以將特定屬性(稱為 資料批註 )套用至您的類別和屬性。 資料註解會覆寫慣例,但會受到 Fluent API 組態覆寫。
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace EFModeling.EntityProperties.DataAnnotations.Annotations;
internal class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
}
[Table("Blogs")]
public class Blog
{
public int BlogId { get; set; }
[Required]
public string Url { get; set; }
}
內建慣例
EF Core 包含預設啟用的許多模型建置慣例。 您可以在實 IConvention 作 介面的類別清單中找到所有它們。 不過,該清單不包含協力廠商資料庫提供者和外掛程式所引進的慣例。
應用程式可以移除或取代上述任何慣例,以及針對 EF 現成無法辨識的模式套用組態的新 自訂慣例 。
提示
以下顯示的程式碼來自 ModelBuildingConventionsSample.cs 。
移除現有的慣例
有時候其中一個內建慣例可能不適合您的應用程式,在此情況下可以移除。
提示
如果您的模型未使用對應屬性(也稱為資料批註)進行設定,則可以安全地移除名稱結尾 AttributeConvention
的所有慣例,以加速模型建置。
範例:不要為外鍵資料行建立索引
建立外鍵 (FK) 資料行的索引通常很合理,因此有內建慣例: ForeignKeyIndexConvention 。 查看與 和 關聯性 Blog
之實體類型的模型 偵錯檢視 ,我們可以看到兩個 Post
索引已建立-一個用於 FK,另一個則用於 AuthorId
BlogId
FK。 Author
EntityType: Post
Properties:
Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd
AuthorId (no field, int?) Shadow FK Index
BlogId (no field, int) Shadow Required FK Index
Navigations:
Author (Author) ToPrincipal Author Inverse: Posts
Blog (Blog) ToPrincipal Blog Inverse: Posts
Keys:
Id PK
Foreign keys:
Post {'AuthorId'} -> Author {'Id'} ToDependent: Posts ToPrincipal: Author ClientSetNull
Post {'BlogId'} -> Blog {'Id'} ToDependent: Posts ToPrincipal: Blog Cascade
Indexes:
AuthorId
BlogId
不過,索引會有額外負荷,而且可能不一定適合為所有 FK 資料行建立它們。 若要達成此目的, ForeignKeyIndexConvention
可以在建置模型時移除 :
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
configurationBuilder.Conventions.Remove(typeof(ForeignKeyIndexConvention));
}
現在查看模型的 Post
偵錯檢視,我們看到尚未建立 FK 上的索引:
EntityType: Post
Properties:
Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd
AuthorId (no field, int?) Shadow FK
BlogId (no field, int) Shadow Required FK
Navigations:
Author (Author) ToPrincipal Author Inverse: Posts
Blog (Blog) ToPrincipal Blog Inverse: Posts
Keys:
Id PK
Foreign keys:
Post {'AuthorId'} -> Author {'Id'} ToDependent: Posts ToPrincipal: Author ClientSetNull
Post {'BlogId'} -> Blog {'Id'} ToDependent: Posts ToPrincipal: Blog Cascade
如有需要,仍然可以針對外鍵資料行明確建立索引,使用 IndexAttribute 或 搭配 中的 OnModelCreating
組態。
偵錯檢視
您可以在 IDE 的偵錯工具中存取模型產生器偵錯檢視。 例如,使用 Visual Studio:
它也可以直接從程式碼存取,例如將偵錯檢視傳送至主控台:
Console.WriteLine(context.Model.ToDebugString());
偵錯檢視有簡短表單和長表單。 長表單也包含所有批註,如果您需要檢視關聯式或提供者特定的中繼資料,可能會很有用。 您也可以從程式碼存取長檢視:
Console.WriteLine(context.Model.ToDebugString(MetadataDebugStringOptions.LongDefault));