11

In ADO.NET, ExecuteNonQuery() "For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command" (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery.aspx)

In EF v1, context.SaveChanges() method returns "The number of objects in an Added, Modified, or Deleted state when SaveChanges was called." (http://msdn.microsoft.com/en-us/library/bb739065.aspx)

Please tell, when multiple entities (or single entity) are added or updated to context and context.SaveChanges() method is called, how to check if actual INSERT or UPDATE was successful.

Can we assume if there was NO exception that INSERT(s) or UPDATE(s) was successful ?

Thank You

Tieson T.
  • 20,774
  • 6
  • 77
  • 92
dev
  • 1,291
  • 3
  • 18
  • 26

4 Answers4

15

Yes, if there is no exception you may assume that the statements executed successfully.

Andrew Peters
  • 11,135
  • 4
  • 37
  • 34
4

In EntityFramework, SaveChangesAsync() returns an int. So you can check if it is > 0 or not.

If something happens with SaveChangesAsync() it will return the number of effected rows and this means if value > 0 then true. So simply, you can have below scenerio:

INSERT

public Task<bool> CreateEntity(Entity entity){

    if(entity == null)
            return false;

    await _dataContext.Entities.AddAsync(entity);

    var created = await _dataContext.SaveChangesAsync();

    return created > 0;
}

UPDATE

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

     _dataContext.Posts.Update(entityToUpdate);

     var updated = await _dataContext.SaveChangesAsync();

     return updated > 0;
}

DELETE

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;
}

And in your methods, now you can simply check if that change is success or not:

For a simple MVC scenerio:

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.
     }
}

You can do the same practice for Update & Delete

Burak
  • 467
  • 4
  • 16
  • Yeah, but if something is wrong these methods will bubble up an exception (f.e. DbUpdateException), so they either always return `true` or throw an exception. It's a long-winded way of saying: everything's OK when no exception is thrown. Also, having separate methods for all CUD actions isn't really useful when working with objects graphs. Saving an object graph may involve both inserts, updates, and deletes. I'd rather just do business and then call `SaveChanges` and let EF decide what should be done. All in all, I'm don't see much merit in what you're proposing here. – Gert Arnold Dec 31 '19 at 16:26
  • I understand your point, but author just asked if there is a way where we can check if the "statement" is a "success" or "fail", so as I've mentioned this is just a simple way of achieving that. This is just a little convertion of the example that author gave above(ADO.Net): ```the return value is the number of rows affected by the command```. – Burak Jan 01 '20 at 23:23
  • 1
    He has just asked if there is a similar approach in EF, it can be a bad practice but after all, in the end of the day **1** is bigger than **0**. You are right when you say **either returns true or throws an exception**. But if question asks : ```Please tell, when multiple entities (or single entity) are added or updated to context and context.SaveChanges() method is called, how to check if actual INSERT or UPDATE was successful.```, So in this approach, if one or more rows are actually effected, then this returns-we can say-- a success. I hope you understand my point of view in here. :) – Burak Jan 01 '20 at 23:25
  • 1
    This is exactly how I do it in EF Core, when I want to know if something is updated or inserted. Glad to see I am not the only one. – AussieJoe Apr 21 '20 at 19:57
  • `SaveChanges` can very well affect 0 records without having errors. The accepted answer is the only correct answer to this question. – Gert Arnold Nov 03 '21 at 12:33
  • If you update without changing any field, SaveChanges would return 0, but I wouldn't consider that a failure. – Davide Visentin Feb 22 '23 at 09:32
2

Maybe this is not direct answer to the question, but may help. By default all commands are encapsulated in one DbTransaction when SaveChanges method is called (Julia Lerman, Programming Entity Framework). So, or all commands will be successfully executed, or neither. That's one way to know if insert, or update or delete was successful.

Misha N.
  • 3,455
  • 1
  • 28
  • 36
-1

define variable SaveStatus var SaveStatus=context.SaveChanges()

then you can know if the creation has been done by getting the value of SaveStatus=1

in the case of "SaveStatus=0" it means no record has been created or affected