我有实体框架核心,它执行我不想要的额外删除。
模型定义:我有两个实体Template
和TemplateVersion
。 TemplateVersion
只是模板的下一个版本,因此TemplateVersion
只有一个Template
(N:1关系)
public class Template
{
public int Id { get; set; }
}
public class TemplateVersion
{
public int Id { get; set; }
public Template Template { get;set; }
}
到目前为止,一切都很清楚。
但是:我希望获得Template
级别的信息,这是TemplateVersion
的当前版本,因此我的Template
定义现在看起来像{{{ 1}}和以前一样)
TemplateVersion
所以我希望public class Template
{
public int Id { get; set; }
public TemplateVersion CurrentVersion { get; set;}
}
N
个TemplateVersion
个实例指向1
的{{1}}实例,但同时Template
指的是Template
1
TemplateVersion
这里的魔术开始了:当我添加一个Template
和一个TemplateVersion
时,一切都运转良好。
Template ---- TemplateVersionPrevious.Template == Template
但当我添加另一个TemplateVersion
实例指向同一个Template
(并更新Template
的{{1}})时,CurrentVersion
的第一个实例突然出现它的TemplateVersion
字段为空。
Template
我认为这是因为实体框架认为我有一个经典的Template ---- TemplateVersionPrevious.Template == null
---- TemplateVersionCurrent.Template == Template
关系,只有1:1
的一个实例可以与同一个TemplateVersion
有关系 - 这是因为{ {1}}字段。
如何告诉Entity Framework它不应该清除我的Template
关系?
其他信息:我将CurrentTemplate
实体定义如下
TemplateVersion
它变得更有趣:TemplateVersion
的上一个实例刚刚被删除!
public class TemplateVersion
{
public int Id { get; set; }
[ForeignKey(nameof(TemplateId))]
public Template Template { get;set; }
public int TemplateId {get;set;}
}
答案 0 :(得分:6)
EF默认约定不适用于2个实体之间的多个关系。并且数据注释不能很好地与一对一关系或单向关联(在一端没有导航属性的关系)。
您需要使用流畅的API显式配置所需的关系。由于流畅的API对于具有/不具有导航属性具有不同的重载并且用于纠正过载很重要,所以假设您的模型与此完全相同(我的意思是导航和显式FK属性影响关系,其他属性无关紧要):
public class Template
{
public int Id { get; set; }
public TemplateVersion CurrentVersion { get; set; }
}
public class TemplateVersion
{
public int Id { get; set; }
public Template Template { get; set; }
}
所需两种关系的流畅配置如下:
modelBuilder.Entity<Template>()
.HasMany<TemplateVersion>()
.WithOne(e => e.Template)
.IsRequired();
modelBuilder.Entity<Template>()
.HasOne(e => e.CurrentVersion)
.WithOne()
.HasForeignKey<Template>("TemplateVersionId")
.IsRequired(false);
请注意,您已定义了循环关系,因此其中一个应该是可选的。我选择Template..TemplateVersionId
作为我认为合乎逻辑的选择。
另请注意,对于一对一关系,主要和从属目标不能从HasOne
/ WithOne
唯一确定,因此您需要使用HasForeignKey
和{{1 泛型类型参数来指定(相反,一对多关系没有这样的问题,因为一方总是主要的,而manu方是依赖的)。
有关详细信息,请参阅Relationships。