비고
이 기능은 쿼리 형식의 이름 아래에 추가되었습니다. 나중에 키가 없는 엔터티 형식으로 이름이 바뀌었습니다.
EF Core 모델은 일반 엔터티 형식 외에도 키 없는 엔터티 형식을 포함할 수 있으며 키 값이 포함되지 않은 데이터에 대해 데이터베이스 쿼리를 수행하는 데 사용할 수 있습니다.
키 없는 엔터티 형식 정의
키 없는 엔터티 형식은 다음과 같이 정의할 수 있습니다.
[Keyless]
public class BlogPostsCount
{
public string BlogName { get; set; }
public int PostCount { get; set; }
}
키 없는 엔터티 형식 특성
키 없는 엔터티 형식은 상속 매핑 및 탐색 속성과 같은 일반 엔터티 형식과 동일한 많은 매핑 기능을 지원합니다. 관계형 저장소에서 흐름 API 메서드 또는 데이터 주석을 통해 대상 데이터베이스 개체 및 열을 구성할 수 있습니다.
그러나 다음과 같은 일반 엔터티 형식과 다릅니다.
- 키를 정의할 수 없습니다.
- DbContext의 변경 내용을 추적하지 않으므로 데이터베이스에 삽입, 업데이트 또는 삭제되지 않습니다.
- 관습에 의해 발견되지 않습니다.
- 특히 탐색 매핑 기능의 하위 집합만 지원합니다.
- 관계의 주된 끝으로 작동할 수 없습니다.
- 소유 엔터티에 대한 탐색이 없을 수 있습니다.
- 일반 엔터티를 가리키는 참조 탐색 속성만 포함할 수 있습니다.
- 엔터티는 키 없는 엔터티 형식에 대한 탐색 속성을 포함할 수 없습니다.
-
[Keyless]데이터 주석이나.HasNoKey()메서드 호출로 구성해야 합니다. - 정의 쿼리에 매핑될 수 있습니다. 정의 쿼리는 키 없는 엔터티 형식의 데이터 원본 역할을 하는 모델에 선언된 쿼리입니다.
- 계층 구조를 가질 수 있지만 TPH로 매핑해야 합니다.
- 테이블 분할 또는 엔터티 분할을 사용할 수 없습니다.
사용 시나리오
키 없는 엔터티 형식에 대한 주요 사용 시나리오 중 일부는 다음과 같습니다.
- SQL 쿼리의 반환 형식으로 사용
- 기본 키가 포함되지 않은 데이터베이스 뷰에 매핑합니다.
- 기본 키가 정의되지 않은 테이블에 매핑합니다.
- 모델에 정의된 쿼리에 매핑합니다.
데이터베이스 개체에 매핑
키 없는 엔터티 형식을 데이터베이스 개체에 매핑하는 작업은 ToTable 또는 ToView Fluent API를 사용하여 수행됩니다. EF Core의 관점에서 이 메서드에 지정된 데이터베이스 개체는 뷰입니다. 즉, 읽기 전용 쿼리 원본으로 처리되며 업데이트, 삽입 또는 삭제 작업의 대상이 될 수 없습니다. 그러나 데이터베이스 개체가 실제로 데이터베이스 뷰여야 한다는 의미는 아닙니다. 또는 읽기 전용으로 처리되는 데이터베이스 테이블일 수 있습니다. 반대로, 일반 엔터티 형식의 경우 EF Core는 메서드에 ToTable 지정된 데이터베이스 개체를 테이블로 처리할 수 있다고 가정합니다. 즉, 쿼리 원본으로 사용할 수 있지만 업데이트, 삭제 및 삽입 작업의 대상이기도 합니다. 실제로 ToTable에 데이터베이스 뷰의 이름을 지정할 수 있습니다. 해당 뷰가 데이터베이스에서 업데이트 가능하도록 구성되어 있으면 모든 기능이 올바르게 작동합니다.
예시
다음 예제에서는 키 없는 엔터티 형식을 사용하여 데이터베이스 뷰를 쿼리하는 방법을 보여줍니다.
팁 (조언)
GitHub에서 이 문서의 샘플을 볼 수 있습니다.
먼저 간단한 블로그 및 게시 모델을 정의합니다.
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public ICollection<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
}
다음으로, 각 블로그와 연결된 게시물 수를 쿼리할 수 있는 간단한 데이터베이스 뷰를 정의합니다.
await db.Database.ExecuteSqlRawAsync(
@"CREATE VIEW View_BlogPostCounts AS
SELECT b.Name, Count(p.PostId) as PostCount
FROM Blogs b
JOIN Posts p on p.BlogId = b.BlogId
GROUP BY b.Name");
다음으로, 데이터베이스 뷰의 결과를 저장할 클래스를 정의합니다.
public class BlogPostsCount
{
public string BlogName { get; set; }
public int PostCount { get; set; }
}
다음으로, API를 사용하여 OnModelCreating 에서 키 없는 엔터티 형식을 HasNoKey 구성합니다.
흐름 구성 API를 사용하여 키 없는 엔터티 형식에 대한 매핑을 구성합니다.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<BlogPostsCount>(
eb =>
{
eb.HasNoKey();
eb.ToView("View_BlogPostCounts");
eb.Property(v => v.BlogName).HasColumnName("Name");
});
}
다음으로 다음을 DbContext 포함하도록 구성합니다.DbSet<T>
public DbSet<BlogPostsCount> BlogPostCounts { get; set; }
마지막으로, 표준 방식으로 데이터베이스 뷰를 쿼리할 수 있습니다.
var postCounts = await db.BlogPostCounts.ToListAsync();
foreach (var postCount in postCounts)
{
Console.WriteLine($"{postCount.BlogName} has {postCount.PostCount} posts.");
Console.WriteLine();
}
팁 (조언)
또한 이 형식에 대한 쿼리의 루트 역할을 하도록 컨텍스트 수준 쿼리 속성(DbSet)을 정의했습니다.
팁 (조언)
인메모리 데이터 공급자를 사용하여 뷰에 매핑된 키 없는 엔터티 형식을 테스트하려면, ToInMemoryQuery을(를) 통해 쿼리에 해당 엔터티 형식을 매핑합니다. 자세한 내용은 메모리 내 공급자 문서를 참조하세요 .
.NET