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.

Leave a Comment

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