C# 已断开从EF核心嵌套集合删除的连接

C# 已断开从EF核心嵌套集合删除的连接,c#,entity-framework-core,asp.net-core-webapi,blazor-webassembly,C#,Entity Framework Core,Asp.net Core Webapi,Blazor Webassembly,我的Blazor应用程序使用Web API获取数据。我正在使用EF Core并通过通用存储库访问数据。我有具有父子关系的实体,其中子实体嵌套在父实体上的集合中。我的代码如下所示: public class Parent { [Required] public long Id { get; set; } [Required] public string Name { get; set; } public virtual ICollection<Ch

我的Blazor应用程序使用Web API获取数据。我正在使用EF Core并通过通用存储库访问数据。我有具有父子关系的实体,其中子实体嵌套在父实体上的集合中。我的代码如下所示:

public class Parent
{
    [Required]
    public long Id { get; set; }

    [Required]
    public string Name { get; set; }

    public virtual ICollection<Child> Children { get; set; }
}

public class Child
{
    [Required]
    public long Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public long ParentId { get; set; }
    public Parent Parent { get; set; }
}

// Repository - generic update method
public virtual async Task<TEntity> UpdateAsync(TEntity entity)
{
    if (entity == null)
    {
        throw new ArgumentNullException($"{nameof(AddAsync)} entity must not be null");
    }

    try
    {
        DbContext.Update(entity);
        await DbContext.SaveChangesAsync();

        return entity;
    }
    catch (Exception ex)
    {
        throw new Exception($"{nameof(entity)} could not be updated: {ex.Message}");
    }
}

// Controller - update for Parent
[HttpPut("{id}")]
public async Task<IActionResult> PutParent(long id, Parent parent)
{
    if (id != parent.Id)
    {
        return BadRequest();
    }
    try
    {
        await Repository.UpdateAsync(parent);
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!ParentExists(id))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }

    return NoContent();
}
公共类父类
{
[必需]
公共长Id{get;set;}
[必需]
公共字符串名称{get;set;}
公共虚拟ICollection子项{get;set;}
}
公营儿童
{
[必需]
公共长Id{get;set;}
[必需]
公共字符串名称{get;set;}
[必需]
公共长父ID{get;set;}
公共父级{get;set;}
}
//存储库-通用更新方法
公共虚拟异步任务UpdateAsync(TEntity实体)
{
if(实体==null)
{
抛出新ArgumentNullException($“{nameof(AddAsync)}实体不能为null”);
}
尝试
{
DbContext.Update(实体);
等待DbContext.saveChangesSync();
返回实体;
}
捕获(例外情况除外)
{
抛出新异常($“{nameof(entity)}无法更新:{ex.Message}”);
}
}
//控制器-父级的更新
[HttpPut(“{id}”)]
公共异步任务PutParent(长id,父级)
{
if(id!=parent.id)
{
返回请求();
}
尝试
{
wait Repository.UpdateAsync(父级);
}
catch(DbUpdateConcurrencyException)
{
如果(!ParentExists(id))
{
返回NotFound();
}
其他的
{
投掷;
}
}
返回NoContent();
}
我的问题是当我从子集合中删除项目时。我希望它们会被删除,但由于更新已断开连接,EF Core显然不认识这一点,也不会删除它们

我已经找到了一些方法使我的应用程序按预期工作,但所有这些都是我所说的“变通方法”

其中之一是添加一个特定于实体的存储库,该存储库以不同方式处理更新,从数据库中查找缺少的行,然后将其标记为删除(请参阅)

虽然这个解决方案适合我,但我希望找到一些解决方案,在基础级别上支持我的应用程序的这种行为,而不需要通过我的每个实体的特定类型存储库来支持它

我已经看到一个建议,使用一些“聪明的孤儿处理”,如在,但我一直无法拿出一个同等的解决方案,为我的情况下,在EF核心。另一个建议是使用中的标识关系,但我也无法让这个建议起作用

我想我一定是做错了什么,因为我觉得奇怪的是,这种预期的行为应该是通过在DbContext中打开或关闭一些选项来支持的


任何帮助都将不胜感激。

目前还没有现成的通用解决方案。我还没有尝试过,但页面包含一个扩展库的链接,名为(“一个具有合成/聚合处理的DTO实体映射器(类似于GraphDiff)。对于EF Core:3,5”),这可能会有所帮助(GraphDiff实际上是EF6的标准)您在创建数据库时采用了什么方法。如果您遵循代码优先的方法,则可以在删除数据时定义操作。有一个选项,如级联,无动作,限制你可以点击[link][1][1]:分离的映射器声音相互干扰,我来看看。删除行为不是这里的问题,因为父对象不会被删除,而只删除嵌套集合中的子对象。