EF 7 First Code – relacja wiele do wielu. DSP16 – część 8

Moim zdaniem ważnym elementem w projekcie jest poprawnie zaprojektowana baza danych. W poście dotyczącym EF7 First Code pokazałem diagram klas:

DSP16-5.1

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:DSP16-8.2

 

Do mojego projektu diagram klas wygląda w następujący sposób:

DSP16-8.1

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 :).

3 thoughts on “EF 7 First Code – relacja wiele do wielu. DSP16 – część 8”

    1. 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!

      1. „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.

Skomentuj Tomasz Jarzyński Cancel Reply

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *