繁体   English   中英

实体框架核心 - 不需要的删除级联

[英]Entity Framework Core - unwanted delete cascade

我有实体框架核心,它执行我不想要的额外删除。

模型定义:我有两个实体TemplateTemplateVersion 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定义现在的样子( TemplateVersion是和以前一样)

public class Template 
{
    public int Id { get; set; }
    public TemplateVersion CurrentVersion { get; set;}
}

所以我想要的是TemplateVersion N实例指向1Template实例,但同时Template指向1 TemplateVersion

这里的魔术开始了:当我添加一个Template和一个TemplateVersion一切都运行良好。

Template ---- TemplateVersionPrevious.Template == Template

但是,当我添加指向同一Template另一个TemplateVersion实例(并更新TemplateCurrentVersion )时, TemplateVersion第一个实例突然将其Template字段置为空。

Template ---- TemplateVersionPrevious.Template == null
         ---- TemplateVersionCurrent.Template == Template

我相信这是因为实体框架认为我有一个经典的1:1关系,并且只有一个TemplateVersion实例可以与同一个Template有关系 - 而且这是因为CurrentTemplate字段。

如何告诉Entity Framework它不应该清除我的TemplateVersion关系?

附加信息:一旦我定义了我的TemplateVersion实体,如下所示

public class TemplateVersion
{
    public int Id { get; set; }
    [ForeignKey(nameof(TemplateId))]
    public Template Template { get;set; }
    public int TemplateId {get;set;}
}

它变得更有趣:之前的TemplateVersion实例刚被删除!

Template ---- TemplateVersionCurrent.Template == Template

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唯一确定,因此您需要使用HasForeignKeyHasPrinciplaKey 泛型类型参数来指定(相反,一对多关系具有没有这样的问题,因为一方总是主要的,而manu方面是依赖的)。

有关详细信息,请参阅关系

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM