How to delete an object by id with entity framework

Entity FrameworkEntity

Entity Framework Problem Overview


It seems to me that I have to retrieve an object before I delete it with entity framework like below

var customer = context.Customers.First(c => c.Id == 1);

context.DeleteObject(customer);

context.Savechanges();

So I need to hit database twice. Is there a easier way?

Entity Framework Solutions


Solution 1 - Entity Framework

In Entity Framework 6 the delete action is Remove. Here is an example

Customer customer = new Customer () { Id = id };
context.Customers.Attach(customer);
context.Customers.Remove(customer);
context.SaveChanges();

Solution 2 - Entity Framework

The same as @Nix with a small change to be strongly typed:

If you don't want to query for it just create an entity, and then delete it.

Customer customer = new Customer () { Id = id };
context.Customers.Attach(customer);
context.Customers.DeleteObject(customer);
context.SaveChanges();

Solution 3 - Entity Framework

Similar question here.

With Entity Framework there is EntityFramework-Plus (extensions library).
Available on NuGet. Then you can write something like:

// DELETE all users which has been inactive for 2 years
ctx.Users.Where(x => x.LastLoginDate < DateTime.Now.AddYears(-2))
     .Delete();

It is also useful for bulk deletes.

Solution 4 - Entity Framework

If you dont want to query for it just create an entity, and then delete it.

Customer customer  = new Customer() {  Id = 1   } ; 
context.AttachTo("Customers", customer);
context.DeleteObject(customer);
context.Savechanges();

Solution 5 - Entity Framework

I am using the following code in one of my projects:

    using (var _context = new DBContext(new DbContextOptions<DBContext>()))
    {
        try
        {
            _context.MyItems.Remove(new MyItem() { MyItemId = id });
            await _context.SaveChangesAsync();
        }
        catch (Exception ex)
        {
            if (!_context.MyItems.Any(i => i.MyItemId == id))
            {
                return NotFound();
            }
            else
            {
                throw ex;
            }
        }
    }

This way, it will query the database twice only if an exception occurs when trying to remove the item with the specified ID. Then if the item is not found, it returns a meaningful message; otherwise, it just throws the exception back (you can handle this in a way more fit to your case using different catch blocks for different exception types, add more custom checks using if blocks etc.).

[I am using this code in a MVC .Net Core/.Net Core project with Entity Framework Core.]

Solution 6 - Entity Framework

This answer is actually taken from Scott Allen's course titled ASP.NET MVC 5 Fundamentals. I thought I'd share because I think it is slightly simpler and more intuitive than any of the answers here already. Also note according to Scott Allen and other trainings I've done, find method is an optimized way to retrieve a resource from database that can use caching if it already has been retrieved. In this code, collection refers to a DBSet of objects. Object can be any generic object type.

        var object = context.collection.Find(id);  
        context.collection.Remove(object);
        context.SaveChanges();

Solution 7 - Entity Framework

dwkd's answer mostly worked for me in Entity Framework core, except when I saw this exception:

> InvalidOperationException: The instance of entity type 'Customer' cannot > be tracked because another instance with the same key value for {'Id'} > is already being tracked. When attaching existing entities, ensure > that only one entity instance with a given key value is attached. > Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to > see the conflicting key values.

To avoid the exception, I updated the code:

Customer customer = context.Customers.Local.First(c => c.Id == id);
if (customer == null) {
    customer = new Customer () { Id = id };
    context.Customers.Attach(customer);
}
context.Customers.Remove(customer);
context.SaveChanges();

Solution 8 - Entity Framework

A smaller version (when compared to previous ones):

var customer = context.Find(id);
context.Delete(customer);
context.SaveChanges();

Solution 9 - Entity Framework

Raw sql query is fastest way I suppose

public void DeleteCustomer(int id)
{
   using (var context = new Context())
   {
      const string query = "DELETE FROM [dbo].[Customers] WHERE [id]={0}";
      var rows = context.Database.ExecuteSqlCommand(query,id);
      // rows >= 1 - count of deleted rows,
      // rows = 0 - nothing to delete.
   }
}

Solution 10 - Entity Framework

From official documentation:

Student studentToDelete = new Student() { ID = id };
_context.Entry(studentToDelete).State = EntityState.Deleted;
await _context.SaveChangesAsync();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJeffView Question on Stackoverflow
Solution 1 - Entity FrameworkdwkdView Answer on Stackoverflow
Solution 2 - Entity FrameworkSawanView Answer on Stackoverflow
Solution 3 - Entity FrameworkacarlonView Answer on Stackoverflow
Solution 4 - Entity FrameworkNixView Answer on Stackoverflow
Solution 5 - Entity FrameworkdemonicdaronView Answer on Stackoverflow
Solution 6 - Entity Frameworkandy_coderView Answer on Stackoverflow
Solution 7 - Entity FrameworkJeffrey RennieView Answer on Stackoverflow
Solution 8 - Entity FrameworkLuis GouveiaView Answer on Stackoverflow
Solution 9 - Entity FrameworkJonikView Answer on Stackoverflow
Solution 10 - Entity FrameworkAbdullah RanaView Answer on Stackoverflow