首页 > 解决方案 > C# EF 核心:更新父行时删除子行

问题描述

大家好,我对 EF 核心版本 6.4.4 有疑问。

我正在开发一个使用 MySQL (8.x) 作为数据库的多线程(不是问题,只是给出上下文)的 .NET core (3.1) 应用程序。

我目前遇到的问题是,当我更新不会导致崩溃的父行时,我的子行被删除,但它会导致数据丢失,因为我每秒都在收集数据以创建图表。

最初我没有这个问题,但是当我开始添加外键约束、索引并稍微重构代码以进行优化时,我突然遇到了这个问题。

我试过的

所以起初我认为EF核心在更新另一个实体时将父级设置为null,或者可能是一些必填字段,其中null导致删除,但事实并非如此,所以我尝试使用Z.EntityFramework.Extensions.EFCore执行单个更新的能力(这意味着我只会更新给定的实体,而不是引用的实体),但这并没有解决它。

我还检查了我所有的索引和外键以允许重复,以确保我没有删除一行,因为它有一个重复的键。我所有的索引都允许重复行(通过设置唯一的 false)。

课程

public  class Parent
{
    
    public int Id { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
    public ParentSatus Status { get; set; } //this is the property that I want to update

    public decimal valueX{ get; set; }

    public decimal valueY{ get; set; }
}

public  class Child
{
    
    public  int Id { get; set; }
    public  string Name { get; set; }
    public  decimal SomeValue{ get; set; }
    public  decimal SomeValue2{ get; set; }
    public string IdForExternalAPI { get; set; }
    public DateTime CreatedAt { get; set; }
    public ChildStatus Status { get; set; }
    public  ChildType Type { get; set; }
    public  virtual Parent Parent { get; private set; }
    public virtual int ParentId { get; set; } //This is for foreignkey constraint stuff see below
}

模型构建器

 protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Child>().HasOne(e => e.Parent).WithOne().HasForeignKey<Child>(e => e.ParentId).OnDelete(DeleteBehavior.Cascade).IsRequired();

        modelBuilder.Entity<Parent>().HasIndex(e => e.SomeIndex).IsUnique(false);
        modelBuilder.Entity<Child>().HasIndex(e => e.ParentId).IsUnique(false);
    }

所以很明显,这种关系是一对一的,这可能是原因,但我不想要一对一,因为父母需要被其他一些类引用,而孩子也是其他一些类的父母.

有人可以帮忙吗?如果有一天我找到它,我会添加答案。

还有一些澄清:我没有添加所有额外的东西,因为它们与这个问题无关,但如果有必要会添加它。

编辑:

我更新父级的代码

 foreach (var parent in parentRepository.ReadParents(new Func<Parent, bool>(e => e.Status == Status.ONGOING)).ToList())
        {
            bool isStillOngoing = //Calculate the current status based on other entities
            if (!isStillOngoing)
            {
               //Do some calculations here
            }

            parent.Status = isStillOngoing ? Status.ONGOING : Status.FINISHED;
            //TODO: Bug here that deletes the child
            parentRepository.UpdateParent(parent);
        }

标签: c#entity-framework

解决方案


好的,我通过扭转关系来解决它。看来我昨天太累了,应该是一对多。

通过更改模型构建器修复。

修复

 protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Parent>().HasMany<Child>().WithOne(e=> e.ParentId).HasForeignKey(e => e.ParentId).OnDelete(DeleteBehavior.Cascade).IsRequired();

    modelBuilder.Entity<Parent>().HasIndex(e => e.SomeIndex).IsUnique(false);
    modelBuilder.Entity<Child>().HasIndex(e => e.ParentId).IsUnique(false);
}

谢谢大家的帮助。


推荐阅读