2012-02-24 9 views
30

Mam modelu jakEntity Framework Kod 4,3 pierwszą wielokrotność wiele do wielu, stosując te same tabele

public class User 
{ 
    [Key] 
    public long UserId { get; set; } 

    [Required] 
    public String Nickname { get; set; } 

    public virtual ICollection<Town> Residencies { get; set; } 

    public virtual ICollection<Town> Mayorships { get; set; } 
} 

i

public class Town 
{ 
    [Key] 
    public long TownId { get; set; } 

    [Required] 
    public String Name { get; set; } 

    public virtual ICollection<User> Residents { get; set; } 
    public virtual ICollection<User> Mayors { get; set; } 
} 

Miałem nadzieję EF stworzy dwa wiele do wielu relacji przy użyciu tworzone automatycznie Tabela TownResidents i TownMayors. Nie mogę znaleźć niezbędnej konwencji lub wyraźnej adnotacji, aby uzyskać ten wynik.

Zamiast tego otrzymuję dwa identyfikatory użytkowników FK w tabeli Town i dwa FK TownIds w tabeli User.

Jakieś pomysły, jak uzyskać EF, aby zobaczyć je w dwóch wielu do wielu relacji?

Dzięki

Odpowiedz

30

Cóż, EF nie posiada jakiś algorytm rozpoznawania słowa i gramatyki, które byłyby wymagane w celu określenia, które (prawdopodobnie) i chcą, że User.ResidenciesTown.Residents tworzą parę właściwości nawigacyjnych i User.Mayorships i Town.Mayors tworzą drugą parę. Dlatego zakłada się, że masz jedną relację jeden-do-wielu i że każda z czterech właściwości nawigacyjnych należy do jednej z relacji. (To jest powód, dla czterech kluczy obcych widzieliście w tabelach bazy danych.)

Ten standard założenie to nie jest to, co chcesz, a więc należy zdefiniować relacje wyraźnie przesłonić tej standardowej konwencji:

albo z adnotacji danych:

public class User 
{ 
    [Key] 
    public long UserId { get; set; } 

    [Required] 
    public String Nickname { get; set; } 

    [InverseProperty("Residents")] 
    public virtual ICollection<Town> Residencies { get; set; } 

    [InverseProperty("Mayors")] 
    public virtual ICollection<Town> Mayorships { get; set; } 
} 

lub Fluent API:

modelBuilder.Entity<User>() 
    .HasMany(u => u.Residencies) 
    .WithMany(t => t.Residents) 
    .Map(x => 
    { 
     x.MapLeftKey("UserId"); 
     x.MapRightKey("TownId"); 
     x.ToTable("TownResidents"); 
    }); 

modelBuilder.Entity<User>() 
    .HasMany(u => u.Mayorships) 
    .WithMany(t => t.Mayors) 
    .Map(x => 
    { 
     x.MapLeftKey("UserId"); 
     x.MapRightKey("TownId"); 
     x.ToTable("TownMayors"); 
    }); 

Fluent API ma tę zaletę, że można sterować Nam e tabeli linków (oraz nazwy kolumn z kluczami). Nie można zdefiniować tych nazw za pomocą adnotacji danych.

+0

Dzięki. Próbowałem obu metod i oboje działali, ale jak powiedziałeś, Fluent Method pozwala kontrolować nazwę tabeli, więc wolę tę metodę. Dzięki jeszcze raz. – Sean

+0

Część Mapa nie jest konieczna. Twój płynny kod api wykonuje pracę bez niego. – ozgur