How to delete an object by id with entity framework

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?

Answers


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();

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();

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.


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();

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


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

If you're using EF 1.0, that is the most concise way to do it. There may be other ways but they're more trouble than they're worth IMHO.


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();

Need Your Help

Freezing columns in wpf datagrid

wpf datagrid wpfdatagrid wpftoolkit

I have some tabular data which has a lot of fields in it, and when my WPF application is resized a lot of them are cut off. However, I want to see the first 6 columns always as they are important. ...

Still getting "Uncaught Error: Bootstrap dropdown require Popper.js" even after including popper.js

javascript jquery angularjs twitter-bootstrap

New to Angular and Bootstrap and I am trying little hands on by creating helloworld app. I have added required libraries but I am stuck at this error