Neu in .NET 6 [16]: N:M-Abstraktion beim Reverse Engineering mit Entity Framework Core

Der Dotnet-Doktor Holger Schwichtenberg  –  13 Kommentare

Beim Reverse Engineering von Datenbanken mit reinen N:M-Zwischentabellen generieren die Entity Framework Core-Werkzeuge seit Version 6.0 nun keine Klassen mehr für die reinen Zwischentabellen, sondern erstellen stattdessen zwei Direktbeziehungen mit ICollection<T>.

Das Feature der N:M-Abstraktion gibt es grundsätzlich schon seit Version 5.0 von Entity Framework Core ("Skip Navigations"), es wurde aber beim Reverse Engineering bisher nicht ausgenutzt.

Als Beispiel dient die Tabellenstruktur aus folgender Abbildung

In Entity Framework Core 1.0 bis 5.0 hat der Befehl Scaffold-DbContext in der NuGet Package Manager Console von Visual Studio beziehungsweise dotnet ef dbcontext scaffold außerhalb von Visual Studio drei Klassen generiert inklusive einer Klasse Flight_Passenger für die Zwischentabelle, jeweils mit 1:N-Beziehungen von Flight und Passenger.

In Entity Framework Core 6.0 gibt es nur noch zwei Klassen: Flight und Passenger haben eine Direktbeziehung.

Folgender Code zeigt die generierte Entitätsklasse Flight:

using System;
using System.Collections.Generic;

namespace BO
{
public partial class Flight
{
public Flight()
{
Passenger_Person = new HashSet<Passenger>();
}

public int FlightNo { get; set; }
public string Airline { get; set; }
public string Departure { get; set; }
public string Destination { get; set; }
public DateTime FlightDate { get; set; }
public bool NonSmokingFlight { get; set; }
public short Seats { get; set; }
public short? FreeSeats { get; set; }
public int? Pilot_PersonID { get; set; }
public string Memo { get; set; }
public bool? Strikebound { get; set; }
public int? Utilization_ { get; set; }
public byte[] Timestamp { get; set; }

public virtual Pilot Pilot_Person { get; set; }

public virtual ICollection<Passenger> Passenger_Person { get; set; }
}
}

Das nächste Listing zeigt die generierte Entitätsklasse Passenger

using System;
using System.Collections.Generic;

namespace BO
{
public partial class Passenger
{
public Passenger()
{
Flight_FlightNo = new HashSet<Flight>();
}

public int PersonID { get; set; }
public DateTime? CustomerSince { get; set; }
public string PassengerStatus { get; set; }

public virtual Person Person { get; set; }

public virtual ICollection<Flight> Flight_FlightNo { get; set; }
}
}

Leider gibt es keinen Schalter, um die N:M-Abstraktion zu verhindern. Wer will, kann sich aber eine Klasse für die Zwischentabelle selbst schreiben und per Fluent-API zusätzlich oder alternativ zur Direktbeziehung einbinden.