假设我在.NET中有一个名为“B”的模型类,它与模型类“A”有一个必需的fk(一对一关系)。
模型的代码应该是这样的:
public class A
{
public int Id { get; set; }
public virtual required B ClassB { get; set; }
}
public class B
{
public int Id { get; set; }
public int A_ID { get; set; }
public virtual required A ClassB { get; set; }
}
现在,假设我在表“A”中有一个id为“1”的记录,我想在类“B”中添加一个fk为该记录1的记录。
在我看来,这段代码应该足够了:
var classBToAdd = new B
{
A_ID = 1
}
_myRepo.Add(classBToAdd);
但我不能这样做,因为关系是必需的:
public virtual required A ClassB { get; set; }
如果不需要,我会收到以下警告:
退出构造函数时,不可为空的变量必须包含非空值。考虑将其声明为可空。
为什么我需要指定完整对象?在某些情况下,这可能意味着我需要执行一个大型查询,以便保存完整的对象。
2条答案
按热度按时间txu3uszq1#
法比奥走在正确的道路上,但有一个更简单的答案。用于标识FK的EF约定基于类型,而不是属性名。这意味着,如果你想声明一个不遵循隐含约定的FK,你需要告诉EF使用什么:用途:
你不需要必填的,因为A和A_ID都是不可空的。现在,如果您想单独创建一个B,并简单地将其与A记录相关联,而不使用ClassA导航属性,那么它应该会像您期望的那样工作。
如果你同时创建一个A和一个B,以最简单的形式:
如果关系Map正确,EF会自动计算插入顺序和FK关联,这是使用ORM与ADO风格的CRUD操作。
我建议不要在EF DbContext之上使用似乎是存储库模式的东西。DbContext已经充当了工作容器的单元,DbSets充当了存储库,因此尝试抽象这些是不必要的,并且容易引入EF可以提供的功能和性能的问题和限制。可以说,在EF之上引入UoW和Repository模式是有正当理由的,例如促进单元测试或实现核心过滤/授权检查,但在开始时,我建议直接使用DbContext和DbSets以避免引入复杂性。
编辑:不可空引用类型错误和EF。编译器将发出警告,如果您的项目选择了严格执行,如果您有一个未填充的必需ClassA,则会出现异常。
解决这个问题最正确的方法是:
其他选项包括:
或者对构造函数使用容错标记:
protected
,否则如果你只是在实体上使用默认构造函数(或者没有构造函数),就把这个标记为public
。83qze16e2#
public int A_ID { get; set; }**不会自动标识外键。正确的代码是:
如果A类对象需要一个还不存在的B类对象,那么如何首先创建A类对象(以获取其引用ID)?
此代码工作:
在Main()中: