7

Miras için bir ebeveyne sahip olması gereken bir İçerik sınıfım var, ancak hiçbir şey olmayan bir alt içerik listesi olmasını istiyorum. Bu miras ağacıyla ilgili.Varlık Çerçeve Kodu Birinci Sınıf, kendi sınıfına sahip ebeveyn ve çocuklar ile aynı sınıftır.

Temelde, ChildContentEnentents with parentContent ve childContent için bir bağlantı tablosu istedim ve Content sınıfının ChildContentRelationship'nin bir listesi olacaktır.

Bu, bir çok hataya neden oldu. İşte

Ben tür EF bu kurarsınız nasıl

public class Content 
{ 
    public int Id { get; set; } 

    public int? ParentContentId { get; set; } 
    public virtual Content ParentContent { get; set; } 

    public string Name { get; set; } 

    public int ContentTypeId { get; set; } 
    public virtual ContentType ContentType { get; set; } 

    public virtual ICollection<Property> Properties { get; set; } 

    public virtual ICollection<ChildContentRelationship> ChildContent { get; set; } 
} 

yapmak istiyorum waht var?

+0

Hangi Varlık Çerçevesi sürümünü kullanıyorsunuz ve ne tür bir yaklaşım kullanıyorsunuz (db-first, model-ilk, kod-ilk)? Ve neden bir bağlantı tablosu istiyorsun? Bire-çok ilişkiniz yok mu, bir ebeveyn * ve * çok * çocuk mu? – Slauma

+0

EF 4.1 +, Kod ilk. Bu ParentContentId yüzünden. Ebeveyn içerik türü şemasından herhangi bir mülkün miras alınabilmesi için İçeriğin bir ebeveyne sahip olmasını isteyeyim. Ancak, bu ağaç hiyerarşisinde olmayan diğer içeriklere referans olması için bir içerik parçası istiyorum.Bu yüzden çocuk içeriği, benzer kontroller yapabilirim. Kontrol olarak isimlendirebilirim ve kontrolümün sahip olduğum bir ContentId var mı? –

+0

"Kod İlk" başlıkta zaten vardı, bana aptal, ben farketmedim, üzgünüm. – Slauma

cevap

18

Modelinizi doğru şekilde anladığımdan emin değilim. Seçenekleri tartışalım.

Bir an için bu ek varlık ChildContentRelationship atlamıyorum ve ChildContent koleksiyonu ICollection<Content> türünde olduğunu varsayalım.

  • Seçenek 1:

    Ben ParentContentters mülkiyet ChildContent ait olduğunu varsayalım. Bu, ContentId = x içeriyorsa ve bu İçeriğin Id = y ile ChildContent'a sahip olduğu anlamına gelirse o zaman ChildContents ParentContentId her zaman x olmalıdır. Bu yalnızca bir ilişki olabilir ve ParentContent ve ChildContent aynı ilişkilendirmenin bitiş noktalarıdır.

    bu ilişki için haritalama oluşturulabilir

    ya veri ek açıklamalarla ...

    [InverseProperty("ParentContent")] 
    public virtual ICollection<Content> ChildContent { get; set; } 
    

    ... ya Akıcı API ile

    :

    modelBuilder.Entity<Content>() 
        .HasOptional(c => c.ParentContent) 
        .WithMany(c => c.ChildContent) 
        .HasForeignKey(c => c.ParentContentId); 
    

    Bunun ne istediğini olmadığını düşünüyorum ("... ile hiçbir ilgisi yok ..."). Navigasyon özelliklerinizi yeniden adlandırmayı düşünün. Birisi Parent... ve Child...'u okursa, muhtemelen aynı ilişki için bir çift gezinme özelliği oluşturduğunu varsayacaktır.

  • Seçenek 2:

    ParentContent aslında iki bağımsız ilişkiler ve her iki ilişkilerin ikinci uç nokta modeliniz sınıfında maruz kalmadığı kıldığı anlamına gelir ChildContent ters özellik değildir.

    ParentContent için haritalama şu şekilde görünecektir: parametreler olmadan

    modelBuilder.Entity<Content>() 
        .HasOptional(c => c.ParentContent) 
        .WithMany() 
        .HasForeignKey(c => c.ParentContentId); 
    

    WithMany() özellikle değilChildContent, ikincisi son nokta modeliniz sınıfında bir özellik olmadığını gösterir.

    Şimdi, soru şu şekilde kalıyor: ChildContent ne tür bir ilişkiye ait?Bire çok mu yoksa çoktan çoğa bir ilişki mi?

    • Seçenek 2a

      bir Content diğer ChildContent s belirtir ve Content çocukları benzersiz edilmektedir (aynı ChildContent s bakınız olan bir ikinci Content olamaz ise, yani konuşmak için) o zaman bir çok ilişki var. (Bu bir emir ve sipariş öğeleri arasındaki bir ilişkiye benzer: Bir sipariş öğe yalnızca bir belirli bir düzen ait olabilir.)

      ChildContent için haritalama şu şekilde görünecektir:

      modelBuilder.Entity<Content>() 
          .HasMany(c => c.ChildContent) 
          .WithOptional(); // or WithRequired() 
      

      Bir olacaktır Veritabanınızdaki bu ilişkilendirmeye ait Content tablosundaki ek yabancı anahtar sütunu, ancak varlık sınıfında karşılık gelen bir FK özelliğine sahip değil.

    • Opsiyon 2b

      birçok Content ler aynı ChildContent s başvurabilirsiniz, o zaman bir çok-çok ilişki vardır. (Bu bir kullanıcı ve roller arasında bir ilişki benzer: Birçok kullanıcı aynı rolü dahilinde olabilir ve kullanıcı birçok role sahip olabilir.)

      ChildContent için haritalama şu şekilde görünecektir:

      modelBuilder.Entity<Content>() 
          .HasMany(c => c.ChildContent) 
          .WithMany() 
          .Map(x => 
          { 
           x.MapLeftKey("ParentId"); 
           x.MapRightKey("ChildId"); 
           x.ToTable("ChildContentRelationships"); 
          }); 
      

      Bu eşleme, veritabanında bir birleştirme tablosu ChildContentRelationships oluşturacaktır, ancak bu tablo için karşılık gelen bir öğeye ihtiyacınız yoktur. Sadece çok-çok ilişki daha iki tuşları (ParentId ve ChildId) ek olarak özelliklerini (CreationDate veya RelationshipType ya da benzeri örnek şey için ...) sahip durumda Seçenek 2c

    • :

      public class ChildContentRelationship 
      { 
          [Key, Column(Order = 0)] 
          public int ParentId { get; set; } 
          [Key, Column(Order = 1)] 
          public int ChildId { get; set; } 
      
          public Content Parent { get; set; } 
          public Content Child { get; set; } 
      
          public DateTime CreationDate { get; set; } 
          public string RelationshipType { get; set; } 
      } 
      

      Şimdi Content sınıf ChildContentRelationship s'lik bir koleksiyona sahip olacaktır: Eğer modele yeni bir varlık ChildContentRelationship tanıtmak zorunda kalacak

      public virtual ICollection<ChildContentRelationship> ChildContent 
          { get; set; } 
      

      Ve iki bire çok ilişkileri vardır:

      modelBuilder.Entity<ChildContentRelationship>() 
          .HasRequired(ccr => ccr.Parent) 
          .WithMany(c => c.ChildContent) 
          .HasForeignKey(ccr => ccr.ParentId); 
      
      modelBuilder.Entity<ChildContentRelationship>() 
          .HasRequired(ccr => ccr.Child) 
          .WithMany() 
          .HasForeignKey(ccr => ccr.ChildId); 
      

Sana seçenek 2a veya 2b ya istediğine inanıyorum, ama emin değilim.

+2

Bunu temizlediğiniz için teşekkürler, seçenek 2b'yi arıyorum, belki de adlandırma gereksinimleri temizleniyor. Bence daha gerçekçi bir kontrol ve belki de farklı bir sınıf/tasarıma ihtiyaç var. Yarın deneyeceğim. –

+1

Bu bir cevap! :) –