如何在实体框架核心模型中使用C#8.0可空引用类型?
我正在.NETCore3.0项目上启用C#8.0可空引用类型。该项目使用Entity Framework Core 3.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
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的引用类型的好处,因为您丢失了所有设计时检查。前者的意思是“我知道标题
在此特定场景中不为空”,因此,如果您错过了一个作业,编译器警告将继续在其他地方发出。?