Wie verwende ich nullbare C # 8.0-Referenztypen mit Entity Framework Core-Modellen?

16

Ich aktiviere C # 8.0 Nullable Reference Types in einem .NET Core 3.0-Projekt. Das Projekt verwendet Entity Framework Core 3.0, um auf die Datenbank zuzugreifen.

Das folgende ist ein Datenmodell, dessen Titel nicht null sein sollte.

public class Vehicle
{
    public int Id { get; private set; } 

    public string Title { get; private set; }

    // Entity Framework Core is instructed to bind to the private _drivers field in a configuration builder
    private readonly List<Driver> _drivers = new List<Driver>();
    public IReadOnlyCollection<Driver> Drivers => _drivers.AsReadOnly();

    private Vehicle() 
    {
    }

    public Vehicle(string title) 
    {
        this.Title = title;
    }

    public void AddDriver(string name)
    {
         this._drivers.Add(new Driver(name));
    }
 }

// A foreign column is defined in a configuration builder
public class Driver
{
    public int Id { get; private set; } 

    public string Name { get; private set; }

    private Driver() 
    {
    }

    public Driver(string name) 
    {
        this.Name = name;
    }
 }

Eigener Code soll die publicKonstruktoren nur verwenden, während die privateKonstruktoren nur dazu da sind, Entity Framework Core und (möglicherweise auch) Serialisierung das Binden von Werten aus der Datenbank an diese Klassen / Modelle zu ermöglichen. Der öffentliche Konstruktor verfügt möglicherweise über eine andere Struktur, Liste und andere Arten von Argumenten als die Eigenschaften des Modells (z. B. enthält er möglicherweise auch Argumente für das erste erforderliche untergeordnete Element, möglicherweise einige optionale Argumente usw.).

Der Compiler generiert jedoch CS8618 Non-nullable field is uninitialized. Consider declaring as nullable.auf den privateKonstruktoren.

Ich kann CS8616 für die privateKonstruktoren von deaktivieren, halte #pragma warning disable CS8618dies jedoch nicht für eine gute Idee.

Wie sollen in diesem Szenario nullfähige C # 8.0-Referenztypen verwendet werden? Oder ist mein Modell falsch oder verstößt gegen Best Practices - wie geht das richtig?

Leider habe ich keine relevanten Dokumente oder Anleitungen gefunden.

alik
quelle

Antworten:

6

Es gibt keine geeignete Möglichkeit, mit nicht nullbaren Navigationsmerkmalen umzugehen.

  1. Die Dokumentation schlägt zwei Möglichkeiten vor und beide sind nicht typsicher. Verwenden Sie ein Hintergrundfeld und lösen Sie InvalidOperationException aus. Es ist unklar, wie es sich davon unterscheidet, nichts zu tun und eine NullReferenceException zu haben
  2. Unterdrücke es mit dem Operator null verzeihend

Offizieller Dokumentationslink: https://docs.microsoft.com/en-us/ef/core/miscellaneous/nullable-reference-types#non-nullable-properties-and-initialization

Mikhail Zhuravlev
quelle
2

Aus den MS Docs for Entity-Typen mit Konstruktoren

Wenn EF Core Instanzen dieser Typen erstellt, z. B. für die Ergebnisse einer Abfrage, ruft es zuerst den standardmäßigen parameterlosen Konstruktor auf und setzt dann jede Eigenschaft auf den Wert aus der Datenbank. Wenn EF Core jedoch einen parametrisierten Konstruktor mit Parameternamen und -typen findet, die mit denen der zugeordneten Eigenschaften übereinstimmen, ruft es stattdessen den parametrisierten Konstruktor mit Werten für diese Eigenschaften auf und legt nicht jede Eigenschaft explizit fest.

Vielleicht lohnt es sich, einen privaten Ctor mit dem für diese Eigenschaften erforderlichen Parameter zu erstellen und zu prüfen, ob das Framework dies dann aufruft und funktioniert?

Das Deaktivieren von Warnungen ist ebenfalls keine gute Idee, es sei denn, Sie sind zu 100% sicher, dass das Deaktivieren in Ordnung ist.

kobiassvilli
quelle