How to delete a list of object using ObjectContext?
Asked Answered
G

4

13

Say you have code like this .

using (CustomerContext db = new CustomerContext())
{
   var foundCustList=db.Customers.Where(c=>c.State=='-1').ToList();//Find all the customer which State is -1
   foreach(var c in foundCustList)
   {
       db.DeleteObject(c);
   }
   db.SaveChanges();//After all the customer is deleted, Commit.
}

But I want to know Is there any way to delete the list of object easily? I don't want to use the foreach to do it one by one for a list . thanks.

Gaulin answered 14/12, 2012 at 6:30 Comment(0)
T
16

You can use EntityFramework.Extended library, which is available from Nuget (don't forget to add using EntityFramework.Extensions;):

db.Customers.Delete(c => c.State == '-1');

Or you can write extension method manually:

public static void DeleteObjects<T>(this ObjectSet<T> set, 
                                    IEnumerable<T> entities)
    where T : EntityObject
{
    foreach (var entity in entities)
        set.DeleteObject(entity);
}

Usage:

var customersToDelete = db.Customers.Where(c => c.State == '-1');
db.Customers.DeleteObjects(customersToDelete);

Or better one:

public static void DeleteObjects<T>(this ObjectSet<T> set, 
                                    Expression<Func<T, bool>> predicate)
    where T : EntityObject
{
    foreach (var entity in set.AsQueryable<T>().Where(predicate))
        set.DeleteObject(entity);
}

Usage:

db.Customers.DeleteObjects(c => c.State == '-1');
Thamora answered 14/12, 2012 at 6:52 Comment(5)
What do you think of Sidharth Mudgal's answer ?Gaulin
@Gaulin db.Customers if of type ObjectSet<T> or Db<Set> - it's not ListThamora
Good point. I think so. I am afraid that EF doesn't know what happen to the Customers changes.Gaulin
@Gaulin when you call DeleteObject EF just changes its state. Real deletion from db will occur when you'll call SaveChanges on context.Thamora
For any googlers, EntityFramework.Extended has been updated; the new syntax is db.Customers.Where(c => c.State == '-1').Delete();.Fishworm
A
10

The accepted answer above is outdated as the syntax has been deprecated in favor of deleting a simple query instead:

db.Customers.Where(c => c.State == '-1').Delete();
Azzieb answered 1/7, 2016 at 1:15 Comment(5)
Have you considered adding a comment to the other answerer (who was last online 11 hours ago, so is probably active on the site), so that they can update their own post? It would've taken less effort than writing up this little rant of yours (which is a shame, since the information buried inside is indeed useful).Interrogate
@AndrasDeak Nope. This is a community forum, not a blog. However, if a couple over-zealous, idealistic, community members wish to protect the integrity of the thread history, rather than the accuracy and accessibility of the of the content, who am I to argue. I like my "rant". If it changes one self-imposed moderators view of things, it served its purpose.Azzieb
@Azzieb Stack Overflow is not a forum, it's a collection of useful answers to useful questions. cf meta.stackexchange.com/a/92110/186209Unmuzzle
@Unmuzzle It is NOT a blog, which was my point. But thank you for yet another off-topic semantically argument. You did however stumble across my original point; the "usefulness" of this thread is enhanced by editing the outdated answer, NOT adding a more current, accurate yet highly obscured answer that users must hunt for. It really is a shame the elitists - more interested in protocol than truth - don't get that.Azzieb
@Azzieb I regret that you find my comment off-topic and that you may see this as elitism. I see that I had missed your point and it does have some merit: old accepted answers can get stale. Note that with enough rep you can edit the answers of others, but my interpretation of the "philosophy" of the site is that you should instead try to add a better answer of your own, even after considering the flaw that you're suggesting. If you're interested I would recommend that you get involved with the meta-discussion site meta.stackoverflow.com: this kind of discussion is definitely on topic there.Unmuzzle
S
6
db.Customers.Where(c => c.State == '-1').ToList().ForEach(db.DeleteObject);
db.SaveChanges();

should be all you need.

Shovelhead answered 14/12, 2012 at 6:34 Comment(3)
Its not part of EF. Its part of List. Use System.Collections.GenericShovelhead
I was using Model View to generate all the entities class code. these are generate by EF . Are you sure RemoveAll is used to delete DB records by EF?Gaulin
@Jow.wang, I mistook RemoveAll to be part of IEnumerable. Anyways made edits. But I think the one-liner with EntityFramework.Extensions might be better as lazyberezovsky said.Shovelhead
B
3

Entity Framework Core

3.1 3.0 2.2 2.1 2.0 1.1 1.0

using (CustomerContext db = new CustomerContext())
{
    var foundCustList=db.Customers.Where(c=>c.State=='-1').ToList();//Find all the customer which State is -1
    db.Customers.RemoveRange(foundCustList);
    db.SaveChanges();//After all the customer is deleted, Commit.
}

Summary:

Removes the given collection of entities from the context underlying the set with each entity being put into the Deleted state such that it will be deleted from the database when SaveChanges is called.

Remarks:

Note that if System.Data.Entity.Infrastructure.DbContextConfiguration.AutoDetectChangesEnabled is set to true (which is the default), then DetectChanges will be called once before delete any entities and will not be called again. This means that in some situations RemoveRange may perform significantly better than calling Remove multiple times would do. Note that if any entity exists in the context in the Added state, then this method will cause it to be detached from the context. This is because an Added entity is assumed not to exist in the database such that trying to delete it does not make sense.

Baugher answered 7/1, 2020 at 7:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.