具有外键的数据库模型的 C# 8 非空引用类型

Mod*_*man 1 c# entity-framework c#-8.0 nullable-reference-types

我正在尝试在我的项目中实现非空引用类型https://dev.to/integerman/safer-code-with-c-8-non-null-reference-types-4f2c。我喜欢它,但有一个关于数据库模型和约束的问题。

有没有办法说值 X 永远不会为 NULL,因为它在数据库中不可为空?

例如:

public class Person
{
      public int Id { get; set; };

      public string Name { get; set; } = "No name set";

      public IEnumerable<Dog> Dogs { get; set; } = new List<Dog>();
}
Run Code Online (Sandbox Code Playgroud)

Person.Name 在数据库中为 nullable=false。有没有办法可以说这个属性永远不为空?现在我必须设置一个默认值。

public class Dog
{
    public int Id { get; set; }
   
    public string Name { get; set; } = "Noname";

    public int PersonId {get; set; }

    public Person Person { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我对狗中的人也有同样的疑问。这是数据库中的外键约束,没有人(所有者)就不能存在狗。有没有办法这么说;我知道这个值永远不会为空,相信我还是类似的东西?

[更新]

有没有办法说值 X 永远不会为 NULL,因为它在数据库中不可为空?

是的,请参阅 Pavel Anikhouski 的回答

你应该这样做吗:

不,请参阅 TomTom 的回答

我认为最好的解决方案是@canton7 最后的评论。他链接到这个;https://learn.microsoft.com/en-us/ef/core/miscellaneous/nullable-reference-types#non-nullable-properties-and-initialization

另一个原因:

public IEnumerable<Dog> Dogs { get; set; } = new List<Dog>();
Run Code Online (Sandbox Code Playgroud)

如果你想找一个这样的人:

var person = _dbcontext.persons.Single(x => x.Name == "John").ToList(); 
Console.log($"John has {person.Dogs.Count} dogs")
Run Code Online (Sandbox Code Playgroud)

每次都会输出 0,因为我们忘记了 .Include(x => x.dogs)。所以这是错误的。

小智 5

不,这没有意义。特别是在数据库实体领域 - 您必须允许 null,因为否则您无法在不自动加载相关对象的情况下加载对象。这最终将迫使您加载大量您可能不需要进行简单查询的数据。

狗可以在没有人的情况下存在。不是在数据库级别,但我可以要求提供所有狗的列表,并且此时对主人不感兴趣。

  • 这不是重点。这些是数据库访问对象。您可以加载狗,即查看狗的名字,而无需加载所有者。这就是为什么我说在数据库中可以保持完整性,但指针可以为空。“空强制”对于数据库对象来说效果不佳,其中加载可能取决于使用情况,而不是完整性。 (3认同)