EF Core 會使用元數據 模型 來描述應用程式的實體類型如何對應至基礎資料庫。 此模型是使用一組 慣例 來建置的 - 啟發學習法,以尋找常見的模式。 然後,您可以使用對應屬性(也稱為資料標註)和/或ModelBuilder方法(也稱為Fluent API)OnModelCreating來自定義模型,這兩者都會覆蓋慣例所執行的組態。
大部分的組態都可以套用至以任何數據存放區為目標的模型。 提供者也可以啟用特定資料存放區特定的設定,也可以忽略不支援或不適用的設定。 如需了解提供者特定的設定文件,請參閱 資料庫提供者 一節。
小提示
您可以在 GitHub 上檢視本文的 範例 。
使用 Fluent API 來設定模型
您可以在您衍生的 Context 中覆寫 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();
}
}
然後,只要從 Configure
中調用 OnModelCreating
方法即可。
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; }
}
每當模型中包含IEntityTypeConfiguration
實體種類時,EF Core 都會使用指定的Book
實作。 實體類型會使用其中一個一般機制包含在模型中。 例如,為實體類型創建一個 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。 查看與和Post
關聯的Blog
實體類型模型Author
,我們可以看到建立了兩個索引--一個用於BlogId
FK,另一個則用於AuthorId
FK。
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));