2016-12-08 3 views
1

RemoveRange()을 1 쿼리 접근 방식으로 실행하는 방법을 찾습니다.1 쿼리 접근 방식으로 RemoveRange를 사용하는 방법 Entity Framework 6

public void Delete() 
{ 
    Record record = new Record() { 
     id = 1, 
     value = 5 
    }; 
    using(SomeContext ctx = new SomeContext()) { 
     ctx.Records.Entry(record).State = EntityState.Deleted; 
     ctx.SaveChanges(); 
    } 
} 

을하지만 같은 접근 방식은 RemoveRange() 작동하지 않습니다 : Remove() 방법으로는 다음과 같이 작동합니다. EF 문서에 따르면이 메서드는 각 엔터티를 EntityState.Deleted으로 설정합니다. 나는 그것을 이해 그렇게 될 경우 -이 작동합니다 :

public void DeleteAll() 
{ 
    List<Record> records = new List<Record>() { 
     new Record() { id = 1, value = 5 }, 
     new Record() { id = 2, value = 10 } 
    }; 
    using(SomeContext ctx = new SomeContext()) { 
     ctx.Records.RemoveRange(records); 
     ctx.SaveChanges(); 
    } 
} 

을이 작동하기 때문에 :

public void DeleteAll() 
{ 
    List<Record> records = new List<Record>() { 
     new Record() { id = 1, value = 5 }, 
     new Record() { id = 2, value = 10 } 
    }; 
    using(SomeContext ctx = new SomeContext()) { 
     foreach(var item in records) 
     { 
      ctx.Entry(item).State = EntityState.Deleted; 
     } 
     ctx.SaveChanges(); 
    } 
} 

을하지만 예외

The object cannot be deleted because it was not found in the ObjectStateManager. 

이 켜지지 않고 발생 수 있습니까 별도의 쿼리를 통해 데이터베이스에서이 메서드를 모두 검색하지 않고이 메서드를 사용합니까?

답변

2

ctx.Entry(item)을 사용하면이 항목을 컨텍스트 추적에 추가 한 다음 편집 할 수 있습니다. RemoveRange을 사용하면 데이터 컨텍스트에 암시 적으로 추가하지 않으므로 예외가 발생합니다. RemoveRange

편집하기 전에 AttachRange를 사용해보십시오 : 그것을 할

대체 방법을. 이것은 조금 뒤에 RemoveRange이 장면 뒤에서 그것을합니다. 먼저 AutoDetectChanges을 비활성화하고 필요한 내용을 제거한 다음 DetectChanges (으)로 전화합니다. 확장 메서드에서 이것을 래핑하여 하나의 라이너로 만들 수 있습니다.

public void DeleteAll() 
{ 
    List<Record> records = new List<Record>() { 
     new Record() { id = 1, value = 5 }, 
     new Record() { id = 2, value = 10 } 
    }; 
    using(SomeContext ctx = new SomeContext()) { 
     ctx.Configuration.AutoDetectChangesEnabled = false; 
     foreach(var item in records) 
     { 
      ctx.Entry(item).State = EntityState.Deleted; 
     } 
     ctx.ChangeTracker.DetectChanges(); 
     ctx.SaveChanges(); 
    } 
} 
+0

에서 촬영

//Find all records in database with an id that is in your record collection var recordsToBeDeleted = ctx.Records.Where(dbr => records.Any(r => r.id == dbr.id)); ctx.Records.RemoveRange(recordsToBeDeleted); context.SaveChanges(); 

솔루션. 사용자 정의 방법을 의미합니까? 충분히 빠를 것입니까? –

+0

EF 코어에만있는 방법 일 수도 있지만 EF6에는 없을 수도 있습니다. 죄송합니다. – Mats391

+0

좋아요, 편집은 제가 요구했던 것입니다. 음식 연습입니까? 'ctx.Records.Where (dbr => records.Any (r => r.id == dbr.id));를 사용하여 데이터베이스에서 콜렉션을 검색하는 것보다 더 빠를 것인가? 또는 상태를 변경하는 것은 똑같습니까? 데이터베이스에서 모든 레코드를 가져 오기 위해 쿼리를 실행합니까? –

0

나는 entity-collection이 분리되어 있으므로 (objectcontext를 생성 할 때) objectContext가 그것을 추적하지 않습니다. 첨부가 필요할 수 있습니다. 당신은 다음과 같이이 작업을 수행 할 수 있습니다 EF 문서의 방법을 찾을 수 없습니다 this thread

+0

감사합니다. 그러나이 작업을 수행하려면 제거하기 전에 데이터베이스에 대한 쿼리를 실행해야합니다. 나는 이러한 객체가 데이터베이스에 있다는 것을 정확히 알고 있으므로 레코드를 먼저 검색하지 않고 레코드를 삭제하고 싶습니다. –