yabancı anahtar olarak bileşik anahtar


91

MVC 3 uygulamasında Entity framework 4.1 kullanıyorum. Birincil anahtarımın iki sütundan (bileşik anahtar) oluştuğu bir varlığım var. Ve bu başka bir varlıkta yabancı anahtar olarak kullanılıyor. İlişki nasıl oluşturulur? Normal senaryolarda kullanırız:

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; }
} 

ama ya kategoride iki sütun anahtarı varsa?

Yanıtlar:


169

Akıcı API'lerden birini kullanabilirsiniz:

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});

    }
}

Veya veri açıklamaları:

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; }
}

Veri açıklamalarının yanı sıra sanal özellikleri (genel sanal Kategori Kategorisi {get; set;}) tutmam gerekir mi?
DotnetSparrow

4
virtualtembel yükleme için gezinme özellikleri gereklidir. virtualskaler özellikler, ekli nesnelerin değişim takibine yardımcı olur.
Ladislav Mrnka

4
Yabancı anahtar tablosunun sütun adları üstte olandan farklı olsaydı ne yapardınız? Örneğin, üründe, sütun adları PCategoryId2, PCategoryId3 gibi görünüyorsa ForeignKey özniteliğini nasıl etiketlersiniz?

Bu çizgiye ilgili olarak: .HasRequired(p => p.Category)ama Productbir özelliği yok Varlık Catagory bir Katagori birleşik anahtar yapmak ancak iki kimlikleri. Lütfen açıklar mısınız, çünkü derlenmeyeceğine inanıyorum ... Teşekkürler!
gdoron Monica'yı

@gdoron: cevabımda Productvar Category.
Ladislav Mrnka

26

En kolay yolun Veri Ek Açıklamasını Gezinti özelliğinde şu şekilde kullanmak olduğuna inanıyorum: [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; }
}

Bu harika çalıştı. Ben de bunu Navigationmülklerde kullanmayı tercih ediyorum . Ancak, cascadeDelete: falsesite genelinde değil, yalnızca bu mülk için nasıl ayar yapabilirim ? Teşekkürler
RoLYroLLs

Bazı durumlarda yabancı anahtar da geçerli tablonun bileşik anahtarının bir parçasıdır. Bu yol çalıştı. Diğer yol (@Ladislov) olmadı. "Yinelenen Sütun özelliği"
D. Kermott

RoLYroLLs: cascadeDelete, geçiş dosyasında (add-migration paket yöneticisi komutunu kullandıktan sonra) ayarlanır. Bir örnek: AddForeignKey ("dbo.Product", "GuidedActivityID", "dbo.GuidedActivity", "ID", cascadeDelete: false);
Christophe
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.