我有 Entity Framework Core,它执行我不想要的额外删除。

模型定义:我有两个实体 TemplateTemplateVersionTemplateVersion 只是模板的下一个版本,所以 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;}
}

所以我想要的是 NTemplateVersion 实例指向 1Template 实例,但同时 Template 指向 1 TemplateVersion
魔法开始了:当我添加一个 Template 和一个 TemplateVersion 时,一切都运行良好。
Template ---- TemplateVersionPrevious.Template == Template

但是,当我添加另一个指向相同 TemplateVersionTemplate 实例(并更新 TemplateCurrentVersion )时, TemplateVersion 的第一个实例突然将其 Template 字段置空。
Template ---- TemplateVersionPrevious.Template == null
         ---- TemplateVersionCurrent.Template == Template

我相信这是因为 Entity Framework 认为我有一个经典的 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 个实体之间的多个关系。并且数据注释不适用于一对一关系或单向关联(一端没有导航属性的关系)。

您需要使用 fluent API 显式配置所需的关系。由于 fluent 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 方是从属方)。

有关更多信息,请参阅 Relationships

关于c# - Entity Framework Core - 不需要的删除级联,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47903328/

10-10 07:54