Como usar tipos de referência anuláveis ​​do C # 8.0 com modelos principais do Entity Framework?

16

Estou ativando tipos de referência anuláveis ​​do C # 8.0 em um projeto do .NET Core 3.0. O projeto usa o Entity Framework Core 3.0 para acessar o banco de dados.

A seguir, é apresentado um modelo de dados cujo título não deve ser nulo.

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

O código próprio deve usar os publicconstrutores apenas enquanto os privateconstrutores estiverem lá apenas para permitir que o Entity Framework Core e (potencialmente também) a serialização vinculem valores do banco de dados a essas classes / modelos. O construtor público pode ter estrutura, lista e tipos de argumentos diferentes das propriedades do modelo (por exemplo, também pode conter argumentos para o primeiro filho necessário, pode ter alguns argumentos opcionais etc.).

No entanto, o compilador gera CS8618 Non-nullable field is uninitialized. Consider declaring as nullable.nos privateconstrutores.

Consigo desativar o CS8616 para os privateconstrutores, #pragma warning disable CS8618mas não considero isso uma boa ideia.

Como é suposto usar tipos de referência anuláveis ​​C # 8.0 neste cenário? Ou meu modelo é falso ou viola as melhores práticas - como fazê-lo corretamente?

Infelizmente, não encontrei documentos ou orientações relevantes.

alik
fonte

Respostas:

6

Não há maneira adequada de lidar com propriedades de navegação não anuláveis.

  1. A documentação sugere duas maneiras e ambas não são do tipo seguro. Use um campo de apoio e ative InvalidOperationException. Não está claro como é diferente de não fazer nada e ter uma NullReferenceException
  2. Suprima-o com o operador perdoador nulo

Link da documentação oficial: https://docs.microsoft.com/en-us/ef/core/misc Miscellaneous / nullable - reference - types#non - nullable - properties - and - initialization

Mikhail Zhuravlev
fonte
2

No MS Docs for Entity types com construtores

Quando o EF Core cria instâncias desses tipos, como para os resultados de uma consulta, ele primeiro chama o construtor sem parâmetros padrão e, em seguida, define cada propriedade com o valor do banco de dados. No entanto, se o EF Core encontrar um construtor parametrizado com nomes e tipos de parâmetros que correspondam aos das propriedades mapeadas, ele chamará o construtor parametrizado com valores para essas propriedades e não definirá cada propriedade explicitamente.

Talvez valha a pena criar um ctor privado com o parâmetro necessário para essas propriedades e ver se o Framework chamará isso e funcionará?

Desabilitar também avisos não é uma boa ideia, a menos que você esteja 100% confiante de que não há problema em desabilitá-lo.

kobiassvilli
fonte