如何在实体框架核心模型中使用C#8.0可空引用类型?

如何在实体框架核心模型中使用C#8.0可空引用类型?,c#,entity-framework,.net-core,entity-framework-core,nullable-reference-types,C#,Entity Framework,.net Core,Entity Framework Core,Nullable Reference Types,我正在.NETCore3.0项目上启用C#8.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 th

我正在.NETCore3.0项目上启用C#8.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 int Id{get;private set;}
公共字符串标题{get;private set;}
//实体框架核心被指示绑定到配置生成器中的private _drivers字段
私有只读列表_drivers=new List();
公共IReadOnlyCollection驱动程序=>_Drivers.AsReadOnly();
私家车()
{
}
公共车辆(字符串标题)
{
这个.Title=Title;
}
public void AddDriver(字符串名称)
{
此._drivers.Add(新驱动程序(名称));
}
}
//外部列在配置生成器中定义
公务舱司机
{
public int Id{get;private set;}
公共字符串名称{get;private set;}
私人司机()
{
}
公共驱动程序(字符串名称)
{
this.Name=Name;
}
}
Own代码应该只使用
公共
构造函数,而
私有
构造函数只是为了允许实体框架核心和(可能还有)序列化将值从数据库绑定到这些类/模型。公共构造函数的结构、列表和参数类型可能与模型的属性不同(例如,它可能还包含第一个必需子级的参数,可能有一些可选参数等)

但是,编译器生成的
CS8618不可为空字段未初始化。在.<代码>私下< /COD>构造函数> 

中考虑声明为空值。<代码>

我可以通过代码< > PraceMARMA警告禁用代码<>私下< /代码>构造函数CS8616,禁用CS8618 但我不认为这是个好主意。 在这种情况下,应该如何使用C#8.0可空引用类型? 或者我的模型是假的或者违反了最佳实践——如何正确地做到这一点


不幸的是,我没有找到相关的文档或指南。

没有适当的方法来处理不可为空的导航属性

  • 文档建议使用两种方法,但这两种方法都不是类型安全的。使用 支持字段并抛出InvalidOperationException。目前尚不清楚如何进行 它不同于什么都不做,并且有一个NullReferenceException
  • 使用空原谅运算符抑制它
  • 官方文档链接:

    来自

    当EF Core创建这些类型的实例时,例如为结果 对于查询,它将首先调用默认的无参数构造函数 然后将每个属性设置为数据库中的值。然而,如果 EF Core查找具有参数名和 与映射属性匹配的类型,则它将调用 参数化构造函数,其中包含这些属性的值和 不会显式设置每个属性

    也许值得创建一个带有这些属性所需参数的私有ctor,看看框架是否会调用它并工作


    另外,禁用警告也不是一个好主意,除非您完全100%相信禁用警告是可以的。

    我同意您的看法-布拉格块很难看。相反,我将为默认构造函数中的不可为null的引用类型分配null原谅运算符,如下所示:

    private Vehicle() 
    {
        Title = null!;
    }
    
    这比使用所述运算符内联初始化属性更干净、更具表现力,如下所示:

    public string Title { get; private set; } = null!;
    
    后一种解决方案的内容是“我知道
    Title
    不为null,无论场景如何”,这实际上否定了不可为null的引用类型的好处,因为您丢失了所有设计时检查。前者的意思是“我知道
    标题
    在此特定场景中不为空”,因此,如果您错过了一个作业,编译器警告将继续在其他地方发出。