两个对象的EF Core保存错误取决于第二个等于一个

Posted

技术标签:

【中文标题】两个对象的EF Core保存错误取决于第二个等于一个【英文标题】:EF Core Saving error for two objects depending on a second equal one 【发布时间】:2021-01-21 09:29:03 【问题描述】:

我有一个很长很长的 POCO 类(“FichaCliente”),在这里我将对其进行简化,强调 ObservableCollection 的属性:


  public int FichaCliente1  get; set; 
  ...
  public int FichaClienteN  get; set; 

  public ObservableCollection<Reclamado> Reclamados  get; set; 

  public int FichaClienteN+2  get; set; 
  ...
  public int FichaClienteN+M  get; set; 

“Reclamado”类也是一个相对较长的 POCO,它具有另一个类作为元素,即 UF 类。因此,我们可以将“Reclamado”理解为:


  public int Reclamado1  get; set; 
  ...
  public int ReclamadoN  get; set; 

  public UF Uf  get; set; 

  public int ReclamadoN+2  get; set; 
  ...
  public int ReclamadoN+M  get; set; 

作为UF类一个简单的POCO如下:


    public int Id  get; set; 
    public string Apelido  get; set; 
    public string Descricao  get; set; 
    public string Municipio  get; set; 

对数据库的 SAVE 操作仅由“SaveFichaAsync”方法处理,简单如下:

public async void SaveFichaAsync(FichaCliente ficha)
    
        using (var context = new DataContext(_dBService))
        
            context.FichasClientes.Update(ficha);
            await context.SaveChangesAsync();

            return;
        
    

可以肯定的是,“FichaCliente”可以根据需要拥有许多“Reclamado”。没关系,它有效! 为了清楚起见,UF 实体相当于我在美国的状态,因此,给定地址属于一个州(城市,州......)。由于“Reclamados”是不同的实体,我可以拥有一个或多个属于同一个 UF 的“Reclamados”。

这就是失败的地方!

如果我为两个或多个不同的“Reclamados”拥有相同的 UF,则会显示一个错误,就好像它保存了两次相同的 UF,尽管它们实际上是不同的,每个都属于不同的“Reclamados”。它不会两次保存相同的 UF。它为每个“Reclamado”保存一个

错误示例如下:

“无法跟踪实体类型‘UF’的实例,因为键值为‘Id: 26’的另一个实例已被跟踪。附加现有实体时,请确保只有一个具有给定键值的实体实例已附上。”

我该如何处理?

【问题讨论】:

您是使用同一个对象 (UF) 还是创建新对象? 它们是不同的实例...每个实例代表不同的“Reclamado”,不一样! 只是更关注代码:我有固定数量的 UF,每个代表一个状态。每当我参考时,我显然使用的是现有的,因为状态只是那些。但是每个实体 UF 都属于不同的实体 Reclamado,所以它们不可能是一样的…… 只需删除行context.FichasClientes.Update(ficha); 所以不会'保存到数据库中? :O 【参考方案1】:

虽然如果您将持久性模型与实际业务代码解耦可以避免这种情况,但要解决您必须在 SaveChangesAsync 之前遍历所有 UF 并针对每个 UF 执行以下操作的问题

context.Entry(uf).State = EntityState.Unchanged;

【讨论】:

错误已更改,即只是它的 Id... 'Reclamado' 无法跟踪,因为已在跟踪另一个具有键值 'Id: 0' 的实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。'... 但是,如果我使用 context.Entry(uf).State = EntityState.Added,它确实有效!!!【参考方案2】:

您的条目已被上下文跟踪。只需删除行 context.FichasClientes.Update(ficha);,您的代码就可以运行。

Update 方法仅在条目未被 Context 跟踪时才有用。 Read more about update

【讨论】:

以上是关于两个对象的EF Core保存错误取决于第二个等于一个的主要内容,如果未能解决你的问题,请参考以下文章

如何在 EF / EF Core 中的第二个表上实现具有某些条件的左连接?

尝试保存第二个任务时服务的“并发”错误

.NET Core 2 - EF Core 错误处理 保存更改

添加第二个 EF 核心数据库后 Blazor 服务器端 docker 容器分段错误

使用 LINQ 查询语法 EF Core C# 的左外连接

EF 错误:在前一个异步操作完成之前在此上下文上启动了第二个操作