Entity Framework 4.3でSystem.Data.Entity.DbSetのすべての要素を削除する最良の方法は何ですか?
dbContext.Database.ExecuteSqlCommand("delete from MyTable");
(冗談ではありません。)
問題は、EFはバッチコマンドをサポートしていないことであり、直接DMLを使用せずにセット内のすべてのエンティティを削除する唯一の方法は次のとおりです。
foreach (var entity in dbContext.MyEntities)
dbContext.MyEntities.Remove(entity);
dbContext.SaveChanges();
または、完全なエンティティのロードを回避するために、少し安いかもしれません:
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();
ただし、どちらの場合も、allエンティティまたはallキープロパティをロードし、セットからエンティティを1つずつ削除する必要があります。さらに、SaveChanges
を呼び出すと、EFはn(=セット内のエンティティの数)のDELETEステートメントをデータベースに送信します。これらのステートメントは、DBで1つずつ(単一のトランザクションで)実行されます。
したがって、単一のDELETEステートメントのみが必要なので、この目的には直接SQLが明らかに望ましいです。
古い投稿ですが、RemoveRangeメソッドがあります:
dbContext.MyEntities.RemoveRange(dbContext.MyEntities);
dbContext.SaveChanges();
コードでそれを行う別の方法を次に示します。
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;
}
}
}
実際にメソッドを呼び出してセットをクリアするには:
myDbContext.DeleteAll<MyPocoClassName>();
すべての要素を削除する場合SQLを記述せずにを実行し、Single Db Callのみを実行します
Entity Framework Extended Library はbatch deleteメソッドを提供します。
context.Users.Delete();
受け入れられた回答では、以下の方法についてのみ言及しています。
context.Database.ExecuteSqlCommand("delete from MyTable");
代わりに代替手段を提供します。すべてのエンティティの読み込みを回避するために使用できるメソッドを記述し、それらをループしてExecuteSqlCommand代わりに。
コンテキストが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 ) );
}
コードの最初のブロックは、ExecuteSqlCommandメソッドで必要なテーブル名を取得します。
using ( var context = new UnitOfWork() )
{
context.MyRepository.DeleteAll();
}
不要があります
context.SaveChanges()
作業ユニットと汎用リポジトリを使用している場合、次のことが役立つ場合があります。
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;
}
}
使用法:
uow.myRepositoryName.DeleteWhere(u => u.RoomId == roomId);
uow.Save();
直接クエリを使用してこれを実現できます。
ent.Database.ExecuteSqlCommand("delete from tablename");