2012-07-08 22 views
59

Çevrimiçi göründüğüm ve Programlama Varlığı Çerçevesi CodeFirst kitabında gördüğüm örneklerden, her iki sınıfta da bir koleksiyonunuz varsa, EF, MembersRecipes ve her sınıfın birincil anahtarı gibi bir eşleme tablosu oluşturur bu tabloya bağlanır. Aşağıda ne zamanÇoktan çoğa eşleme tablosu

Ancak, bunun yerine Recipes tablosunda yeni alan Member_Id ve Members tablodaki bir Recipe_Id denilen olsun.

Yalnızca ikiden çoğa ilişki oluşturan, ancak çoktan çoğa değil, bu yüzden Üye 3'e (4, 5,6) ve Üyeler'e Bağlı Reçete 4'e üye olabildiğim için 3) vb.

Bu eşleme tablosunu oluşturmanın bir yolu var mı? ve eğer öyleyse nasıl "yemek kitapları" gibi başka bir şey ismini veriyorsunuz?

Teşekkür

public abstract class Entity { 
     [Required] 
     public int Id { get; set; } 
    } 

    public class Member : Entity { 
     [Required] 
     public string Name { get; set; } 

     public virtual IList<Recipe> Recipes { get; set; } 
    } 

    public class Recipe : Entity { 
     [Required] 
     public string Name { get; set; } 

     [ForeignKey("Author")] 
     public int AuthorId { get; set; } 
     public virtual Member Author { get; set; } 

      .... 

     public virtual IList<Member> Members { get; set; } 
    } 

GÜNCELLEME: Aşağıda Ben Akıcı API kullanmak etmeyen denedi başka yaklaşımdır ve bir sahibi bayrağıyla Recipe üzerinde AuthorId & Author yerini, ben de yeniden adlandırmış Aşağıdaki örnek Cookbooks'dan MembersRecipes'a kadardır, bu aynı zamanda sorunumu cevaba benzer şekilde düzeltir, ancak belirtildiği gibi başka imalar da vardır.

public class MembersRecipes { 

    [Key, Column(Order = 0)] 
    [ForeignKey("Recipe")] 
    public int RecipeId { get; set; } 
    public virtual Recipe Recipe { get; set; } 

    [Key, Column(Order = 1)] 
    [ForeignKey("Member")] 
    public int MemberId { get; set; } 
    public virtual Member Member { get; set; } 

    public bool Owner { get; set; } 
} 

ve Recipe & Member sınıflarında

Ben

public virtual IList<MembersRecipes> MembersRecipes { get; set; } 
+2

:

Bu

yukarıda Kod İlk eşleştirmeleri oluşturulan tablolardır neden çok süslü bir terim (yük) ile geldiklerini bilmiyorum; ya da sadece ben, ana dilim İngilizce değil :-) Bilgisayar yükü ile genellikle yük kelimesini ilişkilendiriyorum. EF'de, yük, uğursuz bir şey değildir; tablonuzu, kullanıma hazır bir varlık haline getirerek tasarımınızı geleceğe hazırlayabilirsiniz (örneğin, birincil anahtar olarak ek bir kimlik ekleyerek, mevcut çoktan çoğa bileşik pk'nizi dönüştürmeniz gerekir) benzersiz birleşik sütunlar) –

+1

'dan itibaren Sizin durumunuzda, ekstra bir kimlik eklemediniz, bileşik birincil anahtarı korudunuz. Tablodaki Mal sahibi bayrağı, –

+0

@MichaelBuen yüküdür. Veri yükü, ek veri (örneğin ilişkinin yaratma tarihi) ekleyebileceğiniz eşleme tablosunu (ilişki) belirtir. Gizli bir tabloyla çoktan çoğa EF kullanmanız gerekiyorsa, – RHAD

cevap

95

için koleksiyonlar değişti senin DBContext OnModelCreating bu yapın:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{  
    modelBuilder.Entity<Recipe>() 
     .HasMany(x => x.Members) 
     .WithMany(x => x.Recipes) 
    .Map(x => 
    { 
     x.ToTable("Cookbooks"); // third table is named Cookbooks 
     x.MapLeftKey("RecipeId"); 
     x.MapRightKey("MemberId"); 
    }); 
} 

Etrafa da başka bir yol yapmak olabilir, bu kadar aynı, aynı madalyonun sadece başka bir tarafı:

modelBuilder.Entity<Member>() 
    .HasMany(x => x.Recipes) 
    .WithMany(x => x.Members) 
.Map(x => 
{ 
    x.ToTable("Cookbooks"); // third table is named Cookbooks 
    x.MapLeftKey("MemberId"); 
    x.MapRightKey("RecipeId"); 
}); 

Başka örnekler:

http://www.ienablemuch.com/2011/07/using-checkbox-list-on-aspnet-mvc-with_16.html

http://www.ienablemuch.com/2011/07/nhibernate-equivalent-of-entity.html


GÜNCELLEME

kenara senin Yazar mülkiyet döngüsel başvuru önlemek için Yukarıdaki, bu eklemeniz gerekir:

modelBuilder.Entity<Recipe>() 
    .HasRequired(x => x.Author) 
    .WithMany() 
    .WillCascadeOnDelete(false); 

Fikir burada kaynaklı: EF Code First with many to many self referencing relationship çekirdek şeydir

, siz (bir üye örneğidir) Yazar tesiste Reçete koleksiyonları vardır EF (bildirmeleri gerekmektedir WithMany() ile gösterilir); bu şekilde, çevrimsel referans Yazar özelliği üzerinde durdurulabilir.Birçok çoğa yaklaşım yükü * I * Birçok çoğa haritalama denir Varlık Framework'ün deyişiyle Güncelleştirmeniz İlişkin

CREATE TABLE Members(
    Id int IDENTITY(1,1) NOT NULL primary key, 
    Name nvarchar(128) NOT NULL 
); 


CREATE TABLE Recipes(
    Id int IDENTITY(1,1) NOT NULL primary key, 
    Name nvarchar(128) NOT NULL, 
    AuthorId int NOT NULL references Members(Id) 
); 


CREATE TABLE Cookbooks(
    RecipeId int NOT NULL, 
    MemberId int NOT NULL, 
    constraint pk_Cookbooks primary key(RecipeId,MemberId) 
); 
+0

Hızlı cevap için teşekkürler, iyi görünüyor sadece 1 sorun alıyorum. Bu hatayı alıyorum: "Başvurusal ilişki, izin verilmeyen döngüsel bir başvuruyla sonuçlanacaktır. [Kısıtlama adı = FK_Cookbooks_Members_MemberId]" Onun AuthorId Recipe varlık ile ilgili varsayarak kabul ediyorum ama emin değilim. – Pricey

+1

Teşekkürler harika, benzer yazılar buldum ama gerekli ilişkiyi yapılandırmak için lambda ifadesi olmadan WithMany() kullanma fikrini kavramadı: birçok ilişkinin diğer tarafında bir navigasyon özelliği olmadan. Aynı yazara birden fazla tarifle bağlantılı olarak baktığımda daha mantıklı olanı. Teşekkürler! tekrar + 1 yapabilseydim. – Pricey

+0

Bu da bana bazı şeyleri yeniden yapılandırmam gerektiğini ve "Yemek Kitapları" ilişki eşleme tablosunda isteğe bağlı Sahip bayrağını kullanmam gerektiğini ve Yazar özelliği ile elimden geldiğimi düşünmemi sağlıyor, ancak Haritanın bir ürününe özellik ekleyebileceğinizden emin değilim () işlevi. – Pricey