EF Core尝试更新不存在的记录

时间:2020-08-06 17:47:20

标签: c# .net-core entity-framework-core

更新:直到我创建此帖子导致插入失败后,我才看到代码。现在一切正常。不好意思,谢谢您花时间帮助我。

我遇到一个问题,其中EF试图更新不存在的记录。我需要插入记录。

下面的示例代码:

DoStuff(List<ParentObj> listParent, List<OtherParent> listOtherParent)
{
    foreach(var op in otherParent)
    {
        var updateThisParentRecord = listParent.FirstOrDefault(x => x.Id == op.Id);
        if(updateThisParentRecord != null)
        {
            updateThisParentRecord.ChildRecordList.Add(new ChildRecord
            {
                //set relevant props not PK as it is an identity column
                OtherChildObject = new OtherChildObject 
                {
                    //set relevant props not PK as it is an identity column
                }
            });
        }
    }
    await _parentObjectContext.SaveChangesAsync();
}

型号代码:

public partial class ParentObj
{
    public ParentObj()
    {
        ChiledRecordList = new HashSet<ChildRecord>();
    }

    public int Id {get;set;}
    public virtual ICollection<ChildRecord> ChildRecordList {get;set;}
}

public partial class ChildRecord
{
    public int Id {get;set;}
    public int ParentId {get;set;}
    public int OtherChildObject {get;set;}

    public virtual OtherChildObject OtherChildObject {get;set;}
    public virtual ParentObj {get;set;}
}

public partial class OtherChildObject
{
    public OtherChildObj()
    {
        ParentObj = new HashSet<ParentObj>();
        ChildRecord = new Hashset<ChildRecord>();
    }

    public long Id {get;set;}
    //now that I have written this out, the below line seems strange and may 
    //be keyed wrong?
    public virtual ICollection<ParentObj> ParentObj {get;set;}
    public virtual ICollection<ChildRecord> ChildRecord {get;set;}
}

保存时会引发以下异常:

“数据库操作预期会影响1行,但实际上会影响0行。 自加载实体以来,数据可能已被修改或删除。 有关了解和处理乐观并发异常的信息,请参见http://go.microsoft.com/fwlink/?LinkId=527962

这是例外条目列表中的内容:{{Id:1000}修改的EntityType:ChildRecord}

从EF生成的SQL正确创建了OtherChildObject,但它正在尝试更新不存在的ChildRecord。有人知道发生了什么吗?预先感谢

1 个答案:

答案 0 :(得分:2)

DetectChanges honors store-generated key values开始的重大变化:

旧行为

在EF Core 3.0之前,DetectChanges发现的未跟踪实体将 在添加状态下进行跟踪,并在插入时作为新行插入 将调用SaveChanges。

新行为

从EF Core 3.0开始,如果实体使用生成的键值 并设置了一些键值,则该实体将在 修改状态。这意味着该实体的行被假定为 存在,并且将在调用SaveChanges时进行更新。如果钥匙 值未设置,或者实体类型未使用生成的键, 那么新实体仍将像以前一样被跟踪为已添加 版本。

为什么

进行此更改是为了使其工作更轻松,更一致 在使用商店生成的键时,断开实体图的连接。

缓解措施

如果配置了实体类型,此更改可能会中断应用程序 使用生成的键,但为新的键值显式设置 实例。解决方法是将关键属性显式配置为 不使用生成的值。例如,使用流畅的API:

modelBuilder
    .Entity<Blog>()
    .Property(e => e.Id)
    .ValueGeneratedNever();

或带有数据注释:

[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string Id { get; set; }

如果您明确设置了ChildObjects的ID,并且实体使用的是生成的键值,则将在“修改”状态下跟踪它们。