Code First 및 EntityTypeConfiguration
유창한 API를 사용하여 EF 엔티티를 작성하려고합니다 . 고유 제한 조건으로는 기본 키를 작성하는 것이 쉽지만 그렇지 않습니다. 나는 이것을 위해 네이티브 SQL 명령 실행을 제안하는 오래된 게시물을 보았지만 그 목적을 어기는 것 같습니다. EF6에서 가능합니까?
답변
에 EF6.2 , 당신은 사용할 수 있습니다 HasIndex()
유창하게 API를 통해 마이그레이션에 대한 인덱스를 추가 할 수 있습니다.
https://github.com/aspnet/EntityFramework6/issues/274
예
modelBuilder
.Entity<User>()
.HasIndex(u => u.Email)
.IsUnique();
에 EF6.1 이후, 당신이 사용할 수있는 IndexAnnotation()
귀하의 유창한 API에서 마이그레이션을 위해 인덱스를 추가 할 수 있습니다.
http://msdn.microsoft.com/en-us/data/jj591617.aspx#PropertyIndex
다음에 대한 참조를 추가해야합니다.
using System.Data.Entity.Infrastructure.Annotations;
기본 예
다음은 User.FirstName
속성에 인덱스를 추가하는 간단한 사용법입니다.
modelBuilder
.Entity<User>()
.Property(t => t.FirstName)
.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute()));
실제 예 :
보다 현실적인 예는 다음과 같습니다. 여러 속성에 고유 인덱스 를 추가 합니다. User.FirstName
및 User.LastName
인덱스 이름이 “IX_FirstNameLastName”인
modelBuilder
.Entity<User>()
.Property(t => t.FirstName)
.IsRequired()
.HasMaxLength(60)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(
new IndexAttribute("IX_FirstNameLastName", 1) { IsUnique = true }));
modelBuilder
.Entity<User>()
.Property(t => t.LastName)
.IsRequired()
.HasMaxLength(60)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(
new IndexAttribute("IX_FirstNameLastName", 2) { IsUnique = true }));
답변
Yorro의 답변 외에도 속성을 사용하여 수행 할 수도 있습니다.
int
유형 고유 키 조합에 대한 샘플 :
[Index("IX_UniqueKeyInt", IsUnique = true, Order = 1)]
public int UniqueKeyIntPart1 { get; set; }
[Index("IX_UniqueKeyInt", IsUnique = true, Order = 2)]
public int UniqueKeyIntPart2 { get; set; }
데이터 유형이 string
인 경우 MaxLength
속성을 추가해야합니다.
[Index("IX_UniqueKeyString", IsUnique = true, Order = 1)]
[MaxLength(50)]
public string UniqueKeyStringPart1 { get; set; }
[Index("IX_UniqueKeyString", IsUnique = true, Order = 2)]
[MaxLength(50)]
public string UniqueKeyStringPart2 { get; set; }
도메인 / 스토리지 모델 분리 문제가있는 경우 Metadatatype
속성 / 클래스를 사용 하는 것이 옵션이 될 수 있습니다. https://msdn.microsoft.com/en-us/library/ff664465%28v=pandp.50%29.aspx?f= 255 & MSPPError = -2147217396
빠른 콘솔 앱 예제 :
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
namespace EFIndexTest
{
class Program
{
static void Main(string[] args)
{
using (var context = new AppDbContext())
{
var newUser = new User { UniqueKeyIntPart1 = 1, UniqueKeyIntPart2 = 1, UniqueKeyStringPart1 = "A", UniqueKeyStringPart2 = "A" };
context.UserSet.Add(newUser);
context.SaveChanges();
}
}
}
[MetadataType(typeof(UserMetadata))]
public class User
{
public int Id { get; set; }
public int UniqueKeyIntPart1 { get; set; }
public int UniqueKeyIntPart2 { get; set; }
public string UniqueKeyStringPart1 { get; set; }
public string UniqueKeyStringPart2 { get; set; }
}
public class UserMetadata
{
[Index("IX_UniqueKeyInt", IsUnique = true, Order = 1)]
public int UniqueKeyIntPart1 { get; set; }
[Index("IX_UniqueKeyInt", IsUnique = true, Order = 2)]
public int UniqueKeyIntPart2 { get; set; }
[Index("IX_UniqueKeyString", IsUnique = true, Order = 1)]
[MaxLength(50)]
public string UniqueKeyStringPart1 { get; set; }
[Index("IX_UniqueKeyString", IsUnique = true, Order = 2)]
[MaxLength(50)]
public string UniqueKeyStringPart2 { get; set; }
}
public class AppDbContext : DbContext
{
public virtual DbSet<User> UserSet { get; set; }
}
}
답변
고유 색인을보다 유창하게 설정하는 확장 방법은 다음과 같습니다.
public static class MappingExtensions
{
public static PrimitivePropertyConfiguration IsUnique(this PrimitivePropertyConfiguration configuration)
{
return configuration.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute { IsUnique = true }));
}
}
용법:
modelBuilder
.Entity<Person>()
.Property(t => t.Name)
.IsUnique();
다음과 같은 마이그레이션을 생성합니다.
public partial class Add_unique_index : DbMigration
{
public override void Up()
{
CreateIndex("dbo.Person", "Name", unique: true);
}
public override void Down()
{
DropIndex("dbo.Person", new[] { "Name" });
}
}
답변
@ coni2k의 답변은 정확하지만 [StringLength]
작동 하려면 속성을 추가해야합니다. 그렇지 않으면 잘못된 키 예외가 발생합니다 (예 : 아래).
[StringLength(65)]
[Index("IX_FirstNameLastName", 1, IsUnique = true)]
public string FirstName { get; set; }
[StringLength(65)]
[Index("IX_FirstNameLastName", 2, IsUnique = true)]
public string LastName { get; set; }
답변
불행히도 이것은 Entity Framework에서 지원되지 않습니다. 그것은 EF 6의 로드맵에 있었지만 뒤로 밀렸다 : Workitem 299 : Unique Constraints (Unique Indexes)
답변
modelBuilder.Property(x => x.FirstName).IsUnicode().IsRequired().HasMaxLength(50);