EF Core는 메타데이터 모델을 사용하여 애플리케이션의 엔터티 형식이 기본 데이터베이스에 매핑되는 방법을 설명합니다. 이 모델은 일반적인 패턴을 찾는 추론이라는 규칙 집합을 사용하여 빌드됩니다. 그런 다음 매핑 특성(데이터 주석이라고도 함) 및/또는 메서드(ModelBuilder라고도 함)에 대한 호출 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();
}
}
그런 다음 Configure에서 OnModelCreating 메서드를 호출하기만 하면 됩니다.
new BlogEntityTypeConfiguration().Configure(modelBuilder.Entity<Blog>());
어셈블리의 모든 구성 적용
지정된 어셈블리 내에서 구현하는 형식의 모든 구성을 적용할 수 있습니다.
modelBuilder.ApplyConfigurationsFromAssembly(typeof(BlogEntityTypeConfiguration).Assembly);
비고
구성이 적용되는 순서는 정의되지 않으므로 이 메서드는 순서가 중요하지 않은 경우에만 사용해야 합니다.
비고
ApplyConfigurationsFromAssembly 매개 변수가 없는 생성자가 있는 구성 형식만 인스턴스화합니다. 생성자는 public이거나 public이 아닐 수 있습니다. 생성자에 매개 변수가 필요한 형식은 건너뛰고 SkippedEntityTypeConfigurationWarning 로깅됩니다. 이러한 구성을 적용하려면 수동으로 인스턴스화하고 전달합니다 ApplyConfiguration.
엔터티 유형에 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));
.NET