외래 키로 복합 키


92

MVC 3 응용 프로그램에서 Entity Framework 4.1을 사용하고 있습니다. 기본 키가 두 개의 열 (복합 키)로 구성된 엔티티가 있습니다. 그리고 이것은 다른 엔티티에서 외래 키로 사용됩니다. 관계를 만드는 방법? 일반적인 scnerios에서는 다음을 사용합니다.

public class Category
{
    public string CategoryId { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Product> Products { get; set; }
}

public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public string CategoryId { get; set; }

    public virtual Category Category { get; set; }
} 

하지만 카테고리에 두 개의 열 키가 있으면 어떻게 될까요?

답변:


170

유창한 API를 사용할 수 있습니다.

public class Category
{
    public int CategoryId1 { get; set; }
    public int CategoryId2 { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Product> Products { get; set; }
}

public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public int CategoryId1 { get; set; }
    public int CategoryId2 { get; set; }

    public virtual Category Category { get; set; }
}

public class Context : DbContext
{
    public DbSet<Category> Categories { get; set; }
    public DbSet<Product> Products { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Category>()
            .HasKey(c => new {c.CategoryId1, c.CategoryId2});

        modelBuilder.Entity<Product>()
            .HasRequired(p => p.Category)
            .WithMany(c => c.Products)
            .HasForeignKey(p => new {p.CategoryId1, p.CategoryId2});

    }
}

또는 데이터 주석 :

public class Category
{
    [Key, Column(Order = 0)]
    public int CategoryId2 { get; set; }
    [Key, Column(Order = 1)]
    public int CategoryId3 { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Product> Products { get; set; }
}

public class Product
{
    [Key]
    public int ProductId { get; set; }
    public string Name { get; set; }
    [ForeignKey("Category"), Column(Order = 0)]
    public int CategoryId2 { get; set; }
    [ForeignKey("Category"), Column(Order = 1)]
    public int CategoryId3 { get; set; }

    public virtual Category Category { get; set; }
}

가상 속성 (공개 가상 범주 범주 {get; set;})과 데이터 혁신을 유지해야합니까?
DotnetSparrow 2011 년

4
virtual지연로드에는 탐색 속성이 필요합니다. virtual스칼라 속성은 연결된 개체의 변경 내용 추적에 도움이됩니다.
Ladislav Mrnka 2011 년

4
외래 키 테이블의 열 이름이 부모에있는 것과 다른 경우 어떻게 하시겠습니까? 예를 들어, 제품에서 열 이름이 PCategoryId2, PCategoryId3과 같은 경우 ForeignKey 속성에 레이블을 어떻게 지정합니까?

이 라인에 관련하여 : .HasRequired(p => p.Category)하지만 Product의 속성이없는 법인 Catagory catagory의 복합 키을하지만,이 개 ID를. 설명해 주 시겠어요? 컴파일도 안될 거라 믿으 니 ... 고마워요!
gdoron 모니카 지원하고있다

@gdoron : ProductCategory내 대답에.
Ladislav Mrnka 2012-08-29

26

가장 쉬운 방법은 다음과 같이 Navigation 속성에 데이터 주석을 사용하는 것입니다. [ForeignKey("CategoryId1, CategoryId2")]

public class Category
{
    [Key, Column(Order = 0)]
    public int CategoryId1 { get; set; }
    [Key, Column(Order = 1)]
    public int CategoryId2 { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Product> Products { get; set; }
}

public class Product
{
    [Key]
    public int ProductId { get; set; }
    public string Name { get; set; }
    public int CategoryId1 { get; set; }
    public int CategoryId2 { get; set; }

    [ForeignKey("CategoryId1, CategoryId2")]
    public virtual Category Category { get; set; }
}

이것은 훌륭하게 작동했습니다. 나도 이것을 Navigation속성 에 사용하는 것을 선호 합니다. 그러나 cascadeDelete: false사이트 전체가 아닌이 속성에 대해서만 어떻게 설정할 수 있습니까? 감사합니다
RoLYroLLs

어떤 경우에는 외래 키도 현재 테이블의 복합 키의 일부입니다. 이 방법은 효과가있었습니다. 다른 방법 (@Ladislov)은 그렇지 않았습니다. 오류가 발생했습니다 : "Duplicate Column attribute"
D. Kermott

RoLYroLLs : cascadeDelete가 마이그레이션 파일에 설정됩니다 (add-migration 패키지 관리자 명령을 사용한 후). 예 : AddForeignKey ( "dbo.Product", "GuidedActivityID", "dbo.GuidedActivity", "ID", cascadeDelete : false);
Christophe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.