C# 我应该如何删除 DbSet 中的所有元素?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10448684/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 13:56:01  来源:igfitidea点击:

How should I remove all elements in a DbSet?

c#.netentity-framework-4

提问by aknuds1

What's the best way to remove all elements in a System.Data.Entity.DbSet, with Entity Framework 4.3?

使用 Entity Framework 4.3 删除 System.Data.Entity.DbSet 中所有元素的最佳方法是什么?

采纳答案by Slauma

dbContext.Database.ExecuteSqlCommand("delete from MyTable");

(No kidding.)

(不开玩笑。)

The problem is that EF doesn't support any batch commands and the only way to delete all entities in a set using no direct DML would be:

问题是 EF 不支持任何批处理命令,不使用直接 DML 删除集合中所有实体的唯一方法是:

foreach (var entity in dbContext.MyEntities)
    dbContext.MyEntities.Remove(entity);
dbContext.SaveChanges();

Or maybe a litte bit cheaper to avoid loading full entities:

或者可能便宜一点以避免加载完整的实体:

foreach (var id in dbContext.MyEntities.Select(e => e.Id))
{
    var entity = new MyEntity { Id = id };
    dbContext.MyEntities.Attach(entity);
    dbContext.MyEntities.Remove(entity);
}
dbContext.SaveChanges();

But in both cases you have to load allentities or allkey properties and remove the entities one by one from the set. Moreover when you call SaveChangesEF will send n (=number of entities in the set) DELETE statements to the database which also get executed one by one in the DB (in a single transaction).

但在这两种情况下,您都必须加载所有实体或所有关键属性,并从集合中一一删除实体。此外,当您调用SaveChangesEF 时,将向数据库发送 n 个(=集合中的实体数)DELETE 语句,这些语句也将在 DB 中(在单个事务中)一一执行。

So, direct SQL is clearly preferable for this purpose as you only need a single DELETE statement.

因此,出于此目的,直接 SQL 显然更可取,因为您只需要一个 DELETE 语句。

回答by Tim Cooke

Here's another way you can do it in code.

这是您可以在代码中执行此操作的另一种方法。

public static class Extensions
{
    public static void DeleteAll<T>(this DbContext context)
        where T : class
    {
        foreach (var p in context.Set<T>())
        {
            context.Entry(p).State = EntityState.Deleted;
        }
    }
}

To actually call the method and clear the set:

要实际调用该方法并清除该集合:

myDbContext.DeleteAll<MyPocoClassName>();

回答by Fred Johnson

If you are working with a unit of work and generic repository you may find the following useful

如果您正在使用工作单元和通用存储库,您可能会发现以下有用

public virtual void DeleteWhere(Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = "")
        {
            IQueryable<TEntity> query = dbSet;
            if (filter != null)
            {
                query = query.Where(filter);
            }
            foreach (var includeProperty in includeProperties.Split
                (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(includeProperty);
            }

            foreach (var entity in query)
            {
                context.Entry(entity).State = EntityState.Deleted;
            }
        }

Usage:

用法:

uow.myRepositoryName.DeleteWhere(u => u.RoomId == roomId);
uow.Save();

回答by Anestis Kivranoglou

If you want to remove all elements without writing any SQLand only execute a Single Db Call

如果你想在不写任何 SQL 的情况下删除所有元素并且只执行一个Single Db Call

Entity Framework Extended Libraryoffers a batch deletemethod.

实体框架扩展库提供了批量删除的方法。

context.Users.Delete();

回答by Ravindra Devrani

You can achieve it by using a direct query:

您可以通过使用直接查询来实现它:

 ent.Database.ExecuteSqlCommand("delete from tablename");

回答by Ryfcia

As the accepted answer only mentions about the method below:

由于接受的答案仅提及以下方法:

context.Database.ExecuteSqlCommand("delete from MyTable");

and rather gives alternatives to it, I've managed to write a method, which you can use to avoid loading all entities, then looping through them and use ExecuteSqlCommandinstead.

而是提供了替代方案,我设法编写了一个方法,您可以使用它来避免加载所有实体,然后循环遍历它们并改用ExecuteSqlCommand

Assuming using unit of work, where context is DbContext:

假设使用工作单元,其中上下文是 DbContext:

using System.Data.Entity.Core.Objects;
using System.Text.RegularExpressions;

public void DeleteAll()
{
    ObjectContext objectContext = ( (IObjectContextAdapter)context ).ObjectContext;
    string sql = objectContext.CreateObjectSet<T>().ToTraceString();
    Regex regex = new Regex( "FROM (?<table>.*) AS" );
    Match match = regex.Match( sql );
    string tableName = match.Groups[ "table" ].Value;

    context.Database.ExecuteSqlCommand( string.Format( "delete from {0}", tableName ) );
}

First block of code retrievs the table name needed in ExecuteSqlCommandmethod.

第一个代码块检索ExecuteSqlCommand方法中所需的表名。

Usage:

用法:

using ( var context = new UnitOfWork() )
{
    context.MyRepository.DeleteAll();
}

There's no needto call

没有必要打电话

context.SaveChanges()

回答by joeystdio

Old post but there is a RemoveRange method now:

旧帖子,但现在有一个 RemoveRange 方法:

    dbContext.MyEntities.RemoveRange(dbContext.MyEntities);
    dbContext.SaveChanges();