【问题标题】:C# 8 Non-Null Reference Types for Database models with foreign key具有外键的数据库模型的 C# 8 非 Null 引用类型
【发布时间】:2020-02-17 13:26:53
【问题描述】:

我正在尝试在我的项目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>();
}

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

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

[更新]

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

是的,请参阅 Pavel Anikhouski 的回答

你应该这样做:

不,看 TomTom 的回答

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

另一个原因:

public IEnumerable<Dog> Dogs { get; set; } = new List<Dog>();

如果你想得到这样的人:

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

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

【问题讨论】:

标签: c# entity-framework c#-8.0 nullable-reference-types


【解决方案1】:

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

狗可以在没有人的情况下存在。不在数据库级别,但我可以要求所有狗的名单,此时对主人不感兴趣。

【讨论】:

  • 可能他的业务要求所有的狗都属于人。
  • 这不是重点。这些是数据库访问对象。您可以加载狗,即在不加载所有者的情况下查看狗的名称。这就是为什么我在数据库中说保持完整性是可以的,但是这些指针是可以为空的。在加载可能取决于使用而不是完整性的数据库对象中,“null 强制执行”效果不佳。
【解决方案2】:

你可以使用null forgiving operator!

public Person Person { get; set; } = default!;

正如它在 cmets 中指出的那样,您应该小心使用它,因为它适用于任何类型(值或引用类型),您也可以使用 null!

【讨论】:

  • default! 应谨慎使用。好处是它适用于任何类型(和/或“读起来不错”); 缺点 是它适用于任何类型。 int i { get; set; } = default!; 是合法的,但毫无意义; int i { get; set; } = null!; 是不合法的,它有助于表明你可能在错误地认为某些东西是无效的,而实际上它是无效的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
  • 2014-02-09
  • 2021-02-07
  • 1970-01-01
  • 1970-01-01
  • 2012-09-04
相关资源
最近更新 更多