5

Ich habe 3 Klassen in meinem Modell, wie Sie unten sehen können.Definieren von vielen zu vielen Relation in Code ersten Entity Framework

[Table("UserProfile")] 
public class UserProfile 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 

    public string UserName { get; set; } 

    public ICollection<MartialArtUserProfile> MartialArtUserProfiles { get; set; } 
} 

[Table("MartialArt")] 
public class MartialArt 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 

    public string Name { get; set; } 

    public string Description { get; set; } 

    public string IconPath { get; set; } 

    public string ImagePath { get; set; } 

    public ICollection<MartialArtUserProfile> MartialArtUserProfiles { get; set; } 
} 

public class MartialArtUserProfile 
{ 
    public int UserProfileId { get; set; } 
    public UserProfile UserProfile { get; set; } 

    public int MartialArtId { get; set; } 
    public MartialArt MartialArt { get; set; } 
} 

Und ich habe eine Konfigurationsklasse für viele zu viele Beziehung wie folgt:

public class MartialArtUserProfileConfiguration : EntityTypeConfiguration<MartialArtUserProfile> 
{ 
    public MartialArtUserProfileConfiguration() 
    { 
     HasKey(a => new { a.MartialArtId, a.UserProfileId }); 

     HasRequired(a => a.MartialArt) 
      .WithMany(s => s.MartialArtUserProfiles) 
      .HasForeignKey(a => a.MartialArtId) 
      .WillCascadeOnDelete(false); 

     HasRequired(a => a.UserProfile) 
      .WithMany(p => p.MartialArtUserProfiles) 
      .HasForeignKey(a => a.UserProfileId) 
      .WillCascadeOnDelete(false); 
    } 
} 

Nach meiner Entitäten eine Beziehung definieren, wenn ich versuche, -Update-Datenbank in Package Manager Console laufen es heißt:

Ein oder mehrere Validierungsfehler wurden während der Modellgenerierung festgestellt:

\ tSystem.Data.Entity.Edm.EdmEntityType:: EntityType 'MartialArtUserProfile' hat keinen Schlüssel definiert. Definieren Sie den Schlüssel für diesen EntityType. \ tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'MartialArtUserProfiles' basiert auf dem Typ 'MartialArtUserProfile', für den keine Schlüssel definiert sind.

Was mache ich falsch?

Vielen Dank im Voraus,

+0

Benötigen Sie wirklich die MartialArtUserProfile-Klasse oder verwenden Sie sie nur, um die Viele-zu-Viele-Beziehung herzustellen? –

+0

Ich verwende es nur, um die Viele-zu-Viele-Beziehung herzustellen. @Sniffer – anilca

Antwort

8

Wenn ich verstehe, Sie sind einfach eine viel zu viele mit einer transitiven Tabelle zu erstellen versuchen. Wenn dies der Fall ist, ist dies ein anderer Weg, dies zu erreichen. Verwenden Sie die Fluent-API zum Zuordnen wie unten. Sie können den UserProfileToMartialArt zu dem ändern, was der Tabellenname sein soll. Anstatt das Modell MartialArtUserProfile zu erstellen, lassen Sie EF den Mittelweg für Sie schaffen. Dies gibt auch Ihre Schlüssel an, die Sie über den Fehler informieren sollen.

modelBuilder.Entity<UserProfile>() 
    .HasMany(b => b.MartialArts) 
    .WithMany(a => a.UserProfiles) 
    .Map(m => m.MapLeftKey("MartialArtId") 
     .MapRightKey("UserProfileId") 
     .ToTable("UserProfileToMartialArt")); 

In Martialarts Modell

setzen
public IList<UserProfile> UserProfiles { get; set; } 

In Userprofile Modell

setzen
public IList<MartialArt> MartialArts { get; set; } 
+1

Ich habe Rezensionsfeedback erhalten, dass die Verwendung von .Map in fließend, um die oben genannte Beziehung zu definieren, war nicht die beste Vorgehensweise, da die Lösung nach einer Änderung kompiliert werden konnte, und es wäre nicht zur Laufzeit, dass dies offensichtlich ist. Würden Sie vorschlagen, Reflection oder eine andere Methode zu verwenden (aus dem Kopf heraus, indem Sie das Entity-Tabellenattribut und das Mapping einer Konstante zuweisen?) –

6

Versuchen Sie es wie folgt tun:

[Table("UserProfile")] 
public class UserProfile 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 

    public string UserName { get; set; } 

    [InverseProperty("UserProfiles")] 
    public IList<MartialArt> MartialArts { get; set; } 
} 

[Table("MartialArt")] 
public class MartialArt 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 

    public string Name { get; set; } 

    public string Description { get; set; } 

    public string IconPath { get; set; } 

    public string ImagePath { get; set; } 

    [InverseProperty("MartialArts")] 
    public IList<UserProfile> UserProfiles { get; set; } 
} 
+0

Das funktioniert gut für mich. Obwohl ich in einem Szenario bin, in dem es mir wichtig ist, dass * nur * eine Entität mit der anderen verbunden ist. Ist das möglich? Zuerst hatte ich nur eine IList Andere {get; set;}, aber es funktionierte nicht richtig – Mzn

+0

Sprechen Sie über 1 zu 1 Beziehung? –

+0

Ich spreche über eine (one-way) viel-viele Beziehung ... durch one-way ich meine in meinem Code möchte ich eine Navigationseigenschaft. Dies ist keine große Sache, ich frage mich nur, wie, wenn möglich – Mzn

5

In EntityFramework 6.1, brauchen Sie nicht irgendetwas davon zu tun - nur Sammlungen der beiden hinzufügen Typen zu jeder Klasse und alles fügt sich zusammen.

public class UserProfile { 
    public int Id { get; set; } 
    public string UserName { get; set; } 
    public virtual ICollection<MartialArt> MartialArts { get; set; } 

    public UserProfile() { 
     MartialArts = new List<MartialArt>(); 
    } 
} 

public class MartialArt { 
    public int Id { get; set; } 
    public string Name { get; set; } 
    // *snip* 
    public virtual ICollection<UserProfile> UserProfiles { get; set; } 

    public MartialArt() { 
     UserProfiles = new List<UserProfile>(); 
    } 
} 
+0

Awesome, hat für mich gearbeitet. So sollte es sein. Go 6.1 – parliament

+0

Wenn dies eine Weiterentwicklung von Admirs Antwort oben ist (http://stackoverflow.com/a/15328042/489396) und das "Einfallen" auf der Konvention beruht, welche Konventionen sind zwischen der Zuordnungstabelle erforderlich? –

+1

@GusCrawford - Die Mapping-Tabelle wird vollständig vor Ihrem Code verborgen. Sie wird einfach durch zwei Sammlungen des gegenüberliegenden Objekts in Ihrem Code erstellt. –