2014-03-03 1 views
20

테이블에서 여러 행을 삭제하려고합니다. 일반 SQL 서버에서 RemoveRange()를 사용하여 행을 일괄 삭제

이이 간단 할 것 :

DELETE FROM Table 
WHERE 
    Table.Column = 'SomeRandomValue' 
    AND Table.Column2 = 'AnotherRandomValue' 

엔티티 프레임 워크 (6), 그들은 RemoveRange() 방법을 도입했습니다.
그러나 내가 제공 한 where 절을 사용하여 행을 삭제하는 대신 Entity Framework가 데이터베이스를 쿼리하여 where 절과 일치하는 모든 행을 가져오고 기본 키를 사용하여 하나씩 삭제합니다.

EntityFramework의 현재 제한 사항입니까? 또는 RemoveRange()을 잘못 사용하고 있습니까?

db.Tables.RemoveRange(
    db.Tables 
     .Where(_ => _.Column == 'SomeRandomValue' 
      && _.Column2 == 'AnotherRandomValue') 
); 
+0

테이블은 저장소 이름입니까? –

+3

[EntityFramework.Extended] (https://github.com/loresoft/EntityFramework.Extended)에는 ​​[일괄 삭제] 기능이 있습니다 (https://github.com/loresoft/EntityFramework.Extended/wiki/Batch-Update-and- 삭제) – paqogomez

+1

이것을 확인하십시오 : http://stackoverflow.com/questions/2519866/how-do-i-delete-multiple-rows-in-entity-framework-without-foreach –

답변

2

여기에 EF의 한계에 도달했다고 생각합니다. 성능을 유지하려면 가끔 ExecuteSqlCommand을 사용해야합니다.

1

그것은 조금 깨진,

db.Tables.RemoveRange(
    db.Tables 
     .Where(_ => _.Column == 'SomeRandomValue' 
      && _.Column2 == 'AnotherRandomeValue').AsEnumerable().ToList() 
); 
db.SaveChanges(); 
+0

죄송 합니다만, 나는이 코드로 여전히 같은 결과를 얻었습니다. Entity Framework는 내부 쿼리를 실행 한 다음 각 행을 반복하고 삭제합니다. –

0

왜 당신은 그냥 데이터베이스에 어댑터가없는 시도하고 단지 적절한 삭제를 보내

다음은 내가 RemoveRange()를 사용하고 어떻게 당신의 모범에서와 같은 명령?

+3

할 수 있습니다. 그러나 그것은 기본 DELETE 문을 직접 작성해야한다는 것을 의미합니다. 그것은 ORM이 발생하는 지점을 완전히 무효로합니다. 또한 복잡한 WHERE 절을 원한다면 어떻게해야합니까? 많은 다른 WHERE 절을 처리 할 수있는 수퍼 일반 제너릭 어댑터가 있으면 ORM을 기본적으로 구축했습니다. –

1
var db1 = db.Tables 
     .Where(_ => _.Column == 'SomeRandomValue' 
      && _.Column2 == 'AnotherRandomeValue').AsEnumerable().ToList(); 
db.Tables.RemoveRange(db1); 
db.SaveChanges(); 

변수를 사용하여 이동식 목록을 저장하고 RemoveRange()에 전달하십시오.

저는 일반적으로 이렇게 좋아합니다. 희망이 또한 귀하의 경우에 사용할 수 있습니다.

+1

죄송 합니다만, 나는이 코드로 여전히 같은 결과를 얻습니다. Entity Framework는 내부 쿼리를 실행 한 다음 각 행을 반복하고 삭제합니다. –

+0

테이블에 외래 키가있는 경우 [Foreign] Attribute를 사용하여 모델에서 지정하고 – AKASH

0

뒤로 물러서서 생각해보십시오. 레코드를 삭제하기 위해 데이터베이스에서 레코드를 실제로 다운로드 하시겠습니까? 당신이 할 수 있기 때문에 그것은 좋은 생각을하지 않습니다.

아마도 저장 프로 시저를 사용하여 데이터베이스에서 항목을 삭제할 수 있습니까? EF도 그렇게 할 수 있습니다 ...

+1

가상을 사용합니다.이 상황에서 저장 프로 시저가 더 나은 솔루션이라는 데 동의합니다. 그러나 나는 또한 그것이 EF의 짧은 임박이라고 믿는다. 특정 기준과 일치하는 행을 삭제하면 기본 CRUD입니다. 이 작업을 수행하는 저장 프로 시저가 ORM 사용의 이점을 훨씬 능가한다는 사실. 속도 또는 CRUD 작업이 - - 효율적인 디스크 에 크기 - 참조 무결성 그냥 유지하지 않는 데이터를 사용할 수 –

+0

는 간단히 말해서 상태 무엇 "ORM 임피던스 미스 매치"로 알려진 무언가가있다 데이터베이스가 을 위해 설계되어 있다는 것입니다 다시 부팅하거나 시스템 경계를 넘어 데이터를 공유 할 수 있습니다. –

3

당신이 찾고있는 일괄 삭제 라이브러리는 엔터티를로드하지 않고도 LINQ 쿼리에서 데이터베이스의 여러 레코드를 삭제합니다.

이 기능을 지원하는 여러 라이브러리가 존재합니다.

당신은 여기에 목록을 찾을 수 있습니다

: Entity Framework Batch Delete Library

면책 조항 : 나는이 프로젝트의 소유자 해요 Entity Framework Plus

// using Z.EntityFramework.Plus; // Don't forget to include this. 

// DELETE directly in SQL (without loading entities) 
db.Tables.Where(_ => _.Column == 'SomeRandomValue' 
        && _.Column2 == 'AnotherRandomValue') 
     .Delete(); 

// DELETE using a BatchSize  
db.Tables.Where(_ => _.Column == 'SomeRandomValue' 
        && _.Column2 == 'AnotherRandomValue') 
     .Delete(x => x.BatchSize = 1000); 

위키 : EF+ Batch Delete

0

나는이와 함께 자신을 다루고있어 , 그리고 Adi와 동의합니다 - 그냥 SQL을 사용합니다.

나는 로그 테이블에 기존 행을 청소하고있어, 그리고 EF 인 removeRange이 3 초에서와 같은 일을 3 분에 나섭니다 :

DELETE FROM LogEntries WHERE DATEDIFF(day, GETDATE(), Date) < -6 

날짜가 날짜를 포함하는 컬럼의 이름입니다 . 이를 수정하려면 다음과 같은 매개 변수를 사용하십시오.

context.Database.ExecuteSqlCommand 
     ("DELETE FROM LogEntries WHERE DATEDIFF(day, GETDATE(), Date) < @DaysOld", new System.Data.SqlClient.SqlParameter(
         "DaysOld", - Settings.DaysToKeepDBLogEntries)); 

필자의 경우 많은 행이 포함되어 있습니다. 내가 프로젝트를 시작했을 때 많은 데이터가 없었을 때, RemoveRange는 정상적으로 작동했다.

관련 문제