IT Share you

DbSet의 모든 요소를 ​​어떻게 제거해야합니까?

shareyou 2020. 11. 7. 17:54
반응형

DbSet의 모든 요소를 ​​어떻게 제거해야합니까?


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

그러나 두 경우 모두 모든 항목 또는 모든 키 속성 을로드 하고 집합에서 항목을 하나씩 제거해야합니다. 또한 SaveChangesEF 를 호출 하면 n (= 세트의 엔터티 수) DELETE 문을 데이터베이스에 보내며 DB에서 하나씩 실행됩니다 (단일 트랜잭션에서).

따라서 단일 DELETE 문만 필요하므로 직접 SQL이이 목적에 분명히 바람직합니다.


코드로 할 수있는 또 다른 방법이 있습니다.

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

이전 게시물이지만 이제 RemoveRange 메서드가 있습니다.

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

SQL을 작성하지 않고 모든 요소를 ​​제거 하고 단일 Db 호출 만 실행 하려는 경우

Entity Framework 확장 라이브러리일괄 삭제 방법을 제공합니다 .

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

There's no need to call

context.SaveChanges()

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

You can achieve it by using a direct query:

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

참고URL : https://stackoverflow.com/questions/10448684/how-should-i-remove-all-elements-in-a-dbset

반응형