Jer*_*ian 8 entity-framework ef-code-first
在EntityFramework代码的第一个模型中,存在1:1的关系:
public class Child1
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public Child2 Child2 { get; set; }
}
public class Child2
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[ForeignKey("Child1")]
public int Id { get; set; }
public string Name { get; set; }
public Child1 Child1 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当我尝试将一些数据插入数据库时,它抛出异常:
{"A dependent property in a ReferentialConstraint is mapped to a
store-generated column. Column: 'Id'."}
Run Code Online (Sandbox Code Playgroud)
似乎我不能使用自动生成的Id Child2,如何保持此功能并同时成功建立关系?
Jot*_*aBe 22
这里有两个问题,显而易见的问题,如例外.定义一对一关系时,FK也必须是PK.在这种情况下,两个实体的PK和FK都是该Id字段.异常中显示的问题是FK是数据库生成的.因此,如果插入Child1带有相关的Child2,则EF无法设置相关的FK值,Child2因为它是数据库生成的.
第二个问题,即尚未出现,是一对一的关系只是像SQL Server这样的数据库中的理论问题.如果要插入Child1依赖Child2,则需要先插入Child1,然后再插入相关内容Child2.这是对的,但是,ooops,你也必须在插入Child2之前插入Child1,因为Child1还要依赖Child2.因此,拥有纯粹的一对一关系是不可能的.
要解决这个问题,您需要做两件事:
最后,如果你想到它,一对一的关系通常是没有意义的.您可以使用包含两个表中所有列的单个表,因为当表A中存在一行时,它必须存在于表B中,反之亦然.因此,使用单个表具有相同的效果.
但是,如果您仍想使用1对1关系,EF允许您对其进行建模:
modelBuilder.Entity<Child1>()
.HasRequired(c1 => c1.Child2)
.WithRequiredPrincipal(c2 => c2.Child1);
Run Code Online (Sandbox Code Playgroud)
请注意,在这种情况下,EF抽象注意允许您具有一对一的关系,即使它在DB中不存在.但是,必须使用the指定此关系,ModelBuilder因为您需要指定主体和从属端.在这种情况下,主体是Child1和依赖的Child2.请注意,您仍然需要注意数据库生成值的规则.
请注意,这是在DB中使用单个FK Child2从而建模的Child1,而不是从FK Child1到Child2.因此,在DB中是(1)到(0或1)关系,如上所述
public class Child1
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] // Leave as is
public int Id { get; set; }
...
public class Child2
{
//[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[DatabaseGenerated(DatabaseGeneratedOption.None)] // Not db-generated
//[ForeignKey("Child1")] -- specified in the model builder
public int Id { get; set; }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16917 次 |
| 最近记录: |