Moim zdaniem ważnym elementem w projekcie jest poprawnie zaprojektowana baza danych. W poście dotyczącym EF7 First Code pokazałem diagram klas:
Jeżeli się nie mylę to relacjami wiele do wielu EF6 radził sobie bez problemu. Mogłem napisać kod:
public class Player { public int ID { get; set; } public string Name { get; set; } public string Surname { get; set; } public string Email { get; set; } public string Mobile { get; set; } public virtual ICollection<Tournament> Tournaments{ get; set; } } public class Tournament { public Tournament() { } public int ID { get; set; } public int NumberOfPlayers { get; set; } public int Year { get; set; } public int Season { get; set; } public virtual ICollection<Player> Players { get; set; } }
A później poprosić EF o stworzenie dla mnie tabel w bazie danych. EF radził sobie z tym zadaniem bez problemu.
Jednak chcąc użyć EF7 spawy mają się nieco inaczej. Kiedy napisałem taki kod dla klas Player oraz Tournament i wpisałem komendę dnx ef migrations add initial otrzymałem komunikat:
The navigation ‚Tournaments’ on entity type ‚Player’ not not been added to the model, or ignored, or target entityType ignored.
StackOverFlow przyszedł z pomocą. Musiałem wprowadzić klasę pośrednią: PlayerTournament. Tak jakbym projektował bazę danych zgodnie ze sztuką: relacje wiele do wielu potrzebują dodatkowej tabeli.
public class Player { public int ID { get; set; } public string Name { get; set; } public string Surname { get; set; } public string Email { get; set; } public string Mobile { get; set; } public virtual ICollection<PlayerTournament> Tournaments { get; set;} } public class Tournament { public int ID { get; set; } public int NumberOfPlayers { get; set; } public virtual ICollection<PlayerTournament> Players { get; set; } } public class PlayerTournament { public int PlayerID { get; set; } public Player Player { get; set; } public int TournamentID { get; set; } public Tournament Tournament { get; set; } }
Dodatkowo w klasie z moim DBContextem musiałem dodać jedną linijkę:
public class ApplicationContext : DbContext { public DbSet<Player> Players { get; set; } public DbSet<Tournament> Tournaments { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { foreach (var entity in modelBuilder.Model.GetEntityTypes()) { modelBuilder.Entity(entity.Name).ToTable(entity.Name + "s"); } modelBuilder.Entity<PlayerTournament>().HasKey(x => new { x.PlayerID, x.TournamentID }); } }
Linijka ta tworzy w bazie danych klucze obce dla tabeli PlayerTournament. W konsoli wykonałem polecenia: dnx ef migrations add initial i dnx ef database update i baza danych wygląda w następujący sposób:
Do mojego projektu diagram klas wygląda w następujący sposób:
Jednak tym razem nie używam klasy PlayerTournament. Zamiast tego mam klasę Result, która zawiera dodatkowe informacje porównując z PlayerTournament.
public class Player { public int ID { get; set; } public string Name { get; set; } public string Surname { get; set; } public string Email { get; set; } public string Mobile { get; set; } public virtual ICollection<Result> Results { get; set; } public virtual ICollection<PlayerAchievement> PlayerAchievements { get; set; } } public class Result { public int ID { get; set; } public int Place { get; set; } public int Points { get; set; } public int PlayerID { get; set; } public Player Player { get; set; } public int TournamentID { get; set; } public Tournament Tournament { get; set; } } public class Tournament { public Tournament() { } public int ID { get; set; } public int NumberOfPlayers { get; set; } public int Year { get; set; } public int Season { get; set; } public Image WinnerImage { get; set; } public virtual ICollection<Result> Results { get; set; } }
Warto było stworzyć tą dodatkową tabelę, bo mam gdzie przechowywać dodatkowe, przydatne informacje :).
Aby być ścisłym: wiele do wielu to krotność powiązania między relacjami, nie relacja.
Cześć Dawid K.
Powiedziałbym, że to zależy od nomenklatury i kontekstu w jakiej się używa się tych słów. Albo używa się relacja – związek (powiązanie) albo tabela (encja) – relacja. Ale wszystko pochodzi od angielskiego Entity – Relationship.
Jeszcze statystki googla dorzucę:
Związek wiele do wielu: Około 222 000 wyników (0,38 s)
Relacja wiele do wielu: Około 12 800 000 wyników (0,53 s)
Swoją drogą: dzięki. Dzięki Tobie poszukałem na internecie i się czegoś nowego dowiedziałem.
Pozdrawiam!
„tabela (encja) – relacja.” – no właśnie tu jest problem. Większość programistów nie wie, czym w relacyjnych bazach danych są relacje, i z tego wynikają takie kwiatki jak „relacja wiele do wielu”. A przecież tabele są relacjami! Zaś między nimi mogą występować związki lub powiązania (ang. relationship). I to te powiązania mogą mieć krotność, nie tabele. Co niby miałaby oznaczać „krotność tabeli”?
Wyniki z Google mogą być co najwyżej dowodem na popularność, nie na poprawność. „W każdym bądź razie” czy „wziąść” nie są poprawne, mimo tego, że są powszechnie używane.