모델 만들기 및 구성
EF Core는 메타데이터 모델을 사용하여 애플리케이션의 엔터티 형식이 기본 데이터베이스에 매핑되는 방법을 설명합니다. 이 모델은 일반적인 패턴을 찾는 추론이라는 규칙 집합을 사용하여 빌드됩니다. 그런 다음 OnModelCreating에서 매핑 특성(데이터 주석이라고도 함)및/또는 ModelBuilder 메서드 (흐름 API라고도 함) 호출을 사용하여 모델을 사용자 지정할 수 있으며, 둘 다 규칙에 의해 수행되는 구성을 재정의합니다.
대부분의 구성은 데이터 저장소를 대상으로 하는 모델에 적용할 수 있습니다. 또한 공급자는 특정 데이터 저장소와 관련된 구성을 사용하도록 설정할 수 있으며 지원되지 않거나 적용되지 않는 구성을 무시할 수도 있습니다. 공급자 특정 구성에 대한 문서는 데이터베이스 공급자 섹션을 참조하세요.
팁
GitHub에서 이 문서의 샘플을 볼 수 있습니다.
Fluent API를 사용하여 모델 구성
파생된 컨텍스트에서 OnModelCreating
메서드를 재정의하고 흐름 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
을 명시적으로 호출하는 대신 EF Core에서 적절한 구성을 찾아 사용할 수 있도록 엔터티 형식에 EntityTypeConfigurationAttribute을 배치할 수 있습니다. 예시:
[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
형식은 어셈블리에서 자동으로 검색되지 않습니다. 엔터티 형식을 모델에 추가해야 해당 엔터티 형식에서 특성이 검색됩니다.
데이터 주석을 사용하여 모델 구성
일정 특성(데이터 주석이라고 함)을 클래스 및 속성에 적용할 수도 있습니다. 데이터 주석은 규칙을 재정의하지만 흐름 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
및 Author
에 대한 관계가 있는 Post
엔터티 형식에 대한 모델 디버그 보기를 보면 두 개의 인덱스가 만들어진 것을 볼 수 있습니다. 하나는 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