覆盖现有记录

时间:2019-09-13 13:47:40

标签: c# entity-framework-core

我在使用EF Core时遇到以下情况。这是一个具有几个端点的API Web应用程序。对于其中之一,在POST方法中,我收到以下请求:

ParentObject
{
    "Id": 1111,
    "date": "2019-09-12",
    "message": "This is a fake message",
    "childObject": [
        {
        "Id": 1111,
        "date": "2019-09-12",
        "studentId": "2052",
        "quantity": 25,
        },
        {
        "Id": 1111,
        "date": "2019-09-12",
        "studentId": "2054",
        "quantity": 30,
        }
    ]
}

该请求毫无问题地被接收,并一直到EF核心所在的存储库类。在阅读代码之前,只是为您提供一些功能上下文。这个想法是,在childObjects上,我们仅传递需要检测和插入的对象。例如,在上述请求中,第一个子对象已经存在,我们仅修改了数量值。第二个子对象是一个新的对象。

当前,这正常。 EF Core正在检测这些更改并在SQL上执行适当的操作。这是代码:

public void Update(MyObject newObject, MyObject exisitingObject)
{
    try
    {
        //Some code for the fields on Parent Object
        ...


        //Code for the child object
        //EF is smart enough to detect if it's a insert or update based on the PKs
        exisitingObject.childObject = newObject.childObject;
        DbContext.SaveChanges();
    }
    catch (Exception ex)
    {
        throw new Exception($"Error attemting to update existing record. {ex.Message}", ex.InnerException);
    }
}

如前所述,该代码运行良好。问题是什么?

假设我通过了以下请求:

ParentObject
    {
        "Id": 1111,
        "date": "2019-09-12",
        "message": "This is a fake message",
        "childObject": [
            {
            "Id": 1111,
            "date": "2019-09-25",
            "studentId": "3000",
            "quantity": 25,
            }
        ]
    }

相同的父对象,新的子对象。好吧,EF Core中的代码正在获取这些值并覆盖数据库中现有的两个记录。

EF Core是否不应该基于PK来检测到新的子对象是新记录,并且仅执行插入操作而不删除现有记录?

任何帮助/线索都非常欢迎。

2 个答案:

答案 0 :(得分:1)

首先检查数据库的ID是否存在

var x = db.childobjects.Where(c => c.ID == cildobject.ID).FirstOrDeafult();
If (x != null) {
// then make changes to existing (variable x)
}

else {
db.cildobjects.Add(childobject)
}

db.SaveChanges();

答案 1 :(得分:0)

     using (var transaction = new TransactionScope())
        {
            var child = await _dbContext.childObject.FindAsync(child.Id);

            if (child != null)
            {
                _dbContext.Add(child);
            }
            else
            {
                _dbContext.Entry(child).State = EntityState.Modified;
            }
            await _dbContext.SaveChangesAsync();
            transaction.Complete();
        }