在 Entity Framework 中如何检查插入或更新是否成功

12
在ADO.NET中,ExecuteNonQuery()方法“对于UPDATE、INSERT和DELETE语句,返回值是命令所影响的行数”(http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery.aspx)。
在EF v1中,context.SaveChanges()方法返回“当调用SaveChanges时处于添加、修改或删除状态的对象数量”(http://msdn.microsoft.com/en-us/library/bb739065.aspx)。
请问,当将多个实体(或单个实体)添加或更新到上下文,并调用context.SaveChanges()方法时,如何检查实际的INSERT或UPDATE是否成功?
我们可以假设,如果没有异常抛出,那么可以认为INSERT或UPDATE操作已经成功吗?
谢谢。
4个回答

16

是的,如果没有异常,您可以假设语句已成功执行。


4
在EntityFramework中,SaveChangesAsync()返回一个int类型。因此,您可以检查它是否> 0,或者不是
如果SaveChangesAsync()出现问题,它将返回受影响的行数,这意味着if value > 0,则true。因此,您可以简单地像下面这样使用它:

插入

public Task<bool> CreateEntity(Entity entity){

    if(entity == null)
            return false;

    await _dataContext.Entities.AddAsync(entity);

    var created = await _dataContext.SaveChangesAsync();

    return created > 0;
}

更新

public async Task<bool> UpdateEntity(Entity entityToUpdate)
{
     if(entityToUpdate == null)
               return false;

     _dataContext.Posts.Update(entityToUpdate);

     var updated = await _dataContext.SaveChangesAsync();

     return updated > 0;
}

删除

public async Task<bool> DeleteEntity(int entityId)
{
     var entity = await _dataContext.Entities.FindAsync(entityId);

     if (entity == null)
             return false;

     _dataContext.Entities.Remove(entity);

     var deleted = await _dataContext.SaveChangesAsync();

     return deleted > 0;
}

在你的方法中,现在可以简单地检查该更改是否成功:

对于一个简单的MVC场景:

public Task<IActionResult> CreateEntity(EntityModel model)
{
     if(model == null)
            return StatusCode(404);

     var entity = new Entity
     {
          attribute1 = model.attribute1,
          attribute2 = model.attribute3
     };

     var isCreated = await _entityService.CreateEntity(entity);

     if(isCreated)
     {
          //do something and return a view.
     }
     else
     {
         //you can return a status code, or an error view.
     }
}

您可以采用相同的方法来练习“更新和删除”。

是的,但如果出现问题,这些方法将引发异常(例如DbUpdateException),因此它们要么始终返回“true”,要么抛出异常。这是说:当没有抛出异常时,一切都正常。此外,在使用对象图时,为所有CUD操作单独创建方法并不真正有用。保存对象图可能涉及插入、更新和删除。我宁愿只做业务,然后调用“SaveChanges”,让EF决定应该做什么。总的来说,我认为你在这里提出的建议并没有多大价值。 - Gert Arnold
我理解您的观点,但作者只是询问是否有一种方法可以检查“语句”是“成功”还是“失败”,所以正如我之前提到的,这只是实现这一目标的简单方法。这只是对作者上面给出的示例(ADO.Net)的简单转换:返回值是命令影响的行数 - Burak
1
他刚刚问是否在EF中有类似的方法,这可能是一种不好的做法,但归根结底,10更重要。当你说“要么返回true,要么抛出异常”时,你是正确的。但如果问题是这样问的:请告诉我,当多个实体(或单个实体)被添加或更新到上下文中,并调用context.SaveChanges()方法时,如何检查实际的INSERT或UPDATE是否成功。在这种方法中,如果一个或多个行实际上受到影响,则返回-我们可以说-成功。我希望你能理解我的观点。 :) - Burak
1
这正是我在 EF Core 中执行的方法,当我想要知道某个东西是否被更新或插入时。很高兴看到我不是唯一一个这样做的人。 - AussieJoe
“SaveChanges” 可能会在没有错误的情况下不影响任何记录。 接受的答案是这个问题唯一正确的答案。 - Gert Arnold
如果您更新时没有更改任何字段,SaveChanges将返回0,但我不认为这是一个失败。 - Davide Visentin

2
也许这不是对问题的直接回答,但可能会有所帮助。当调用SaveChanges方法时,默认情况下所有命令都封装在一个DbTransaction中(Julia Lerman,《编程实体框架》)。因此,所有命令要么成功执行,要么全部失败。这是知道插入、更新或删除是否成功的一种方式。请注意保留HTML标签。

“或者都不是”表示为什么?当不成功时会抛出异常吗? - zwcloud

-1

定义变量SaveStatus var SaveStatus=context.SaveChanges()

然后,您可以通过获取SaveStatus=1的值来了解创建是否已完成

在“SaveStatus=0”的情况下,这意味着没有记录被创建或受影响


1
不保存更改(SaveChanges)也可以在没有错误的情况下不影响任何记录。接受的答案是这个问题唯一正确的答案。 - Gert Arnold
我同意你的观点,但如果你想确保记录已经被添加或更新, SaveChanges应该返回1。 - عبدالرحمن شافعى

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接