[英]Entity Framework Core - unwanted delete cascade
I have Entity Framework Core which performs additional delete which I don't want. 我有实体框架核心,它执行我不想要的额外删除。
Model definition: I have two entities Template
and TemplateVersion
. 模型定义:我有两个实体Template
和TemplateVersion
。 A TemplateVersion
are just next versions of template, so TemplateVersion
has one Template
(N:1 relation) 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; }
}
And up to now all is clear an working good. 到目前为止,一切都清楚是一种有益的工作。
BUT : I want to have information on Template
level which is the current version of TemplateVersion
, so my Template
definition now looks like ( TemplateVersion
is the same as before) 但是 :我想有信息Template
水平,这是当前版本的TemplateVersion
,所以我的Template
定义现在的样子( TemplateVersion
是和以前一样)
public class Template
{
public int Id { get; set; }
public TemplateVersion CurrentVersion { get; set;}
}
So what I want to have is N
instances of TemplateVersion
to point to 1
instance of Template
but in the same time Template
is pointing to 1
TemplateVersion
所以我想要的是TemplateVersion
N
实例指向1
个Template
实例,但同时Template
指向1
TemplateVersion
And here the magic starts: when I add one Template
and one TemplateVersion
all is working good. 这里的魔术开始了:当我添加一个Template
和一个TemplateVersion
一切都运行良好。
Template ---- TemplateVersionPrevious.Template == Template
But when I add another instance of TemplateVersion
pointing to the same Template
(and update Template
's CurrentVersion
) suddenly first instance of TemplateVersion
has its Template
field nulled. 但是,当我添加指向同一Template
另一个TemplateVersion
实例(并更新Template
的CurrentVersion
)时, TemplateVersion
第一个实例突然将其Template
字段置为空。
Template ---- TemplateVersionPrevious.Template == null
---- TemplateVersionCurrent.Template == Template
I believe that it's because Entity Framework is thinking that I have a classic 1:1
relation and only one instance of TemplateVersion
can have relation to the same Template
- and it's because of CurrentTemplate
field. 我相信这是因为实体框架认为我有一个经典的1:1
关系,并且只有一个TemplateVersion
实例可以与同一个Template
有关系 - 而且这是因为CurrentTemplate
字段。
How can I tell Entity Framework that it should not clear my TemplateVersion
relation? 如何告诉Entity Framework它不应该清除我的TemplateVersion
关系?
Additional info: once I define my TemplateVersion
entity as follows 附加信息:一旦我定义了我的TemplateVersion
实体,如下所示
public class TemplateVersion
{
public int Id { get; set; }
[ForeignKey(nameof(TemplateId))]
public Template Template { get;set; }
public int TemplateId {get;set;}
}
it's get even more interesting: previous instance of TemplateVersion
is just deleted! 它变得更有趣:之前的TemplateVersion
实例刚被删除!
Template ---- TemplateVersionCurrent.Template == Template
EF default conventions don't play well with multiple relationships between 2 entities. EF默认约定不适用于2个实体之间的多个关系。 And data annotations don't play well with one-to-one relationships or unidirectional associations (relationships without navigation property at one of the ends). 并且数据注释不能很好地与一对一关系或单向关联(在一端没有导航属性的关系)。
You need to explicitly configure the desired relationships with fluent API. 您需要使用流畅的API显式配置所需的关系。 Since fluent API have different overloads for having/not having navigation property and it's important to use to correct overload, let say your model is exactly like this (by exactly I mean the navigation and explicit FK properties which affect the relationships, other properties are irrelevant): 由于流畅的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; }
}
the fluent configuration of the desired two relationships is as follows: 所需两种关系的流畅配置如下:
modelBuilder.Entity<Template>()
.HasMany<TemplateVersion>()
.WithOne(e => e.Template)
.IsRequired();
modelBuilder.Entity<Template>()
.HasOne(e => e.CurrentVersion)
.WithOne()
.HasForeignKey<Template>("TemplateVersionId")
.IsRequired(false);
Note that you have defined circular relationship, hence one of them should be optional. 请注意,您已定义了循环关系,因此其中一个应该是可选的。 I've choosen Template..TemplateVersionId
to be the optional wich sounds logical to me. 我选择了Template..TemplateVersionId
作为我认为合乎逻辑的选择。
Also note that for one-to-one relationships, the principal and dependent ends cannot be uniquely determined from HasOne
/ WithOne
, so you need to use HasForeignKey
and HasPrinciplaKey
generic type argument to specify that (in contrast, one-to-many relationships have no such issue because the one side is always the principal and manu side is the dependent). 另请注意,对于一对一关系,主要和从属端不能从HasOne
/ WithOne
唯一确定,因此您需要使用HasForeignKey
和HasPrinciplaKey
泛型类型参数来指定(相反,一对多关系具有没有这样的问题,因为一方总是主要的,而manu方面是依赖的)。
For more info, see Relationships . 有关详细信息,请参阅关系 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.