Как использовать C # 8.0 обнуляемые ссылочные типы с базовыми моделями Entity Framework?

16

Я включаю C # 8.0 Обнуляемые ссылочные типы в проекте .NET Core 3.0. Проект использует Entity Framework Core 3.0 для доступа к базе данных.

Ниже приведена модель данных, название которой не должно быть нулевым.

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

Предполагается, что собственный код будет использовать publicконструкторы только тогда, когда privateконструкторы существуют только для того, чтобы позволить Entity Framework Core и (возможно, также) сериализации связывать значения из базы данных с этими классами / моделями. Открытый конструктор может иметь структуру, список и типы аргументов, отличные от свойств модели (например, он также может содержать аргументы для первого обязательного дочернего элемента, некоторые аргументы могут быть необязательными и т. Д.).

Тем не менее, компилятор генерирует CS8618 Non-nullable field is uninitialized. Consider declaring as nullable.на privateконструкторы.

Я могу отключить CS8616 для privateконструкторов, #pragma warning disable CS8618но я не считаю это хорошей идеей.

Как предполагается использовать C # 8.0 Nullable Reference Types в этом сценарии? Или моя модель фальшивая или нарушает лучшие практики - как это сделать правильно?

К сожалению, я не нашел соответствующих документов или рекомендаций.

Алик
источник

Ответы:

6

Не существует правильного способа обработки ненулевых навигационных свойств.

  1. Документация предлагает два способа, и оба не являются безопасными. Используйте вспомогательное поле и генерируйте исключение InvalidOperationException. Неясно, чем он отличается от ничего не делать и имеет исключение NullReferenceException
  2. Подавить это с нулевым прощающим оператором

Официальная ссылка на документацию: https://docs.microsoft.com/en-us/ef/core/miscellaneous/nullable-reference-types#non-nullable-properties-and-initialization

Михаил Журавлев
источник
2

Из MS Docs для типов сущностей с конструкторами

Когда EF Core создает экземпляры этих типов, например, для результатов запроса, он сначала вызывает конструктор по умолчанию без параметров, а затем устанавливает для каждого свойства значение из базы данных. Однако, если EF Core найдет параметризованный конструктор с именами параметров и типами, которые совпадают с именами сопоставленных свойств, он вместо этого вызовет параметризованный конструктор со значениями для этих свойств и не будет явно устанавливать каждое свойство.

Возможно, стоит создать частный ctor с параметром, необходимым для этих свойств, и посмотреть, будет ли Framework вызывать его и работать?

Отключение предупреждений также не является хорошей идеей, если вы не уверены на 100%, что отключить его можно.

kobiassvilli
источник