Comment utiliser les types de référence Nullable C # 8.0 avec les modèles Entity Framework Core?

16

J'active les types de référence Nullable C # 8.0 sur un projet .NET Core 3.0. Le projet utilise Entity Framework Core 3.0 pour accéder à la base de données.

Voici un modèle de données dont le titre ne doit pas être nul.

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;
    }
 }

Le propre code est censé utiliser les publicconstructeurs uniquement tandis que les privateconstructeurs sont là juste pour permettre à Entity Framework Core et (éventuellement aussi) à la sérialisation de lier les valeurs de la base de données à ces classes / modèles. Le constructeur public peut avoir une structure, une liste et des types d'arguments différents de ceux des propriétés du modèle (par exemple, il peut également contenir des arguments pour le premier enfant requis, certains arguments peuvent être facultatifs, etc.).

Cependant, le compilateur génère CS8618 Non-nullable field is uninitialized. Consider declaring as nullable.sur les privateconstructeurs.

Je peux désactiver CS8616 pour les privateconstructeurs par #pragma warning disable CS8618mais je ne considère pas cela comme une bonne idée.

Comment est-il censé utiliser les types de référence Nullable C # 8.0 dans ce scénario? Ou mon modèle est-il faux ou viole-t-il les meilleures pratiques - comment le faire correctement?

Malheureusement, j'ai trouvé des documents ou des conseils non pertinents.

alik
la source

Réponses:

6

Il n'existe aucun moyen approprié de gérer les propriétés de navigation non nullables.

  1. La documentation suggère deux façons et les deux ne sont pas sécuritaires. Utilisez un champ de sauvegarde et lancez InvalidOperationException. On ne sait pas en quoi cela diffère de ne rien faire et d'avoir une exception NullReferenceException
  2. Supprimez-le avec l'opérateur de pardon nul

Lien vers la documentation officielle: https://docs.microsoft.com/en-us/ef/core/miscivers/nullable-reference-types#non-nullable-properties-and-initialization

Mikhail Zhuravlev
la source
2

À partir de MS Docs pour les types d'entité avec des constructeurs

Lorsque EF Core crée des instances de ces types, comme pour les résultats d'une requête, il appelle d'abord le constructeur sans paramètre par défaut, puis définit chaque propriété sur la valeur de la base de données. Cependant, si EF Core trouve un constructeur paramétré avec des noms et des types de paramètres qui correspondent à ceux des propriétés mappées, il appellera alors le constructeur paramétré avec des valeurs pour ces propriétés et ne définira pas chaque propriété explicitement.

Peut-être qu'il vaut la peine de créer un ctor privé avec le paramètre nécessaire pour ces propriétés et de voir si le Framework appellera alors cela et fonctionnera?

De plus, la désactivation des avertissements n'est pas une bonne idée, sauf si vous êtes entièrement sûr à 100% qu'il est correct de le désactiver.

kobiassvilli
la source