2012-03-29 3 views
2

엔트리라는 엔티티가 여러 TimeWindows에 연결되어 있습니다. 모든 시간 창을 지우고 새 창을 추가하고 싶습니다.Entity Framework의 모든 관련 엔터티 삭제하기

target.TimeWindows.Clear(); 

을하지만 정말 삭제하지 않았고, 단지 는 항목에 TimeWindows에서 외래 키가 있기 때문에 예외가 발생 관계를 제거 할을 시도 : 처음에 나는 시도했다. 그리고 나는이 작업을 수행해야한다고 생각 :

foreach (var tw in target.TimeWindows) 
    context.DeleteObject(tw); 

하지만 컬렉션에 foreach 문 내부에 수정 된 이후이뿐만 아니라 예외를 throw합니다.

while (target.TimeWindows.Count > 0) 
    context.DeleteObject(target.TimeWindows.Last()); 

을하지만 지금은 그것이 SQL SELECT COUNT 문이 실행되도록 할 수 있기 때문에, Count 속성을 사용하는 방법에 대한 약간의 걱정 : 그래서 나는이 생각했다. 그거야? 그렇다면 Entity Framework에서 모든 시간 창을 어떻게 삭제할 수 있습니까?

+1

아니요, 'Count'는 데이터베이스에서 'SELECT COUNT'을 트리거하지 않으며, 악화됩니다 :-). 그것은'SELECT * FROM TimeWindows WHERE TargetId = @ P0'을 수행하고 메모리 내 수집을 계산합니다. – Steven

+0

오 마이 갓 !! 그럼 당신 제안은 뭐니?! – Rafid

+2

엔티티를 삭제하려면 먼저 엔티티를 메모리에로드해야합니다. 모든 O/RM 도구가 이러한 방식으로 작동합니다. Entity Framework도 마찬가지입니다. 성능이 너무 낮 으면 삭제를 수행하는 저장 프로 시저를 작성하십시오. – Steven

답변

3

탐색 속성의 호출 횟수는 지연로드가 활성화되어 있고 속성이 아직로드되지 않은 경우에만 선택을 발생시킵니다. 따라서 첫 번째 호출은 다음과 같은 결과를 가져올 수 있습니다.

SELECT * FROM TimeWindows WHERE TargetId = @targetId 

모든 계산 결과는로드 된 데이터에서만 실행됩니다.

또한 두 번째 예외를 방지하기 위해 이것을 사용할 수 있습니다 :

foreach (var tw in target.TimeWindows.ToList()) 
    context.DeleteObject(tw); 

을 아니면 identifying relation을 지원하는 데이터베이스 및 모델을 변경할 수 있습니다 (FK는 부모의 뜻에 시간 창의 PK의 일부가되었다)와 같은 경우에 귀하의 첫 번째 코드 스 니펫이 작동합니다.

+0

그러나 ToList()를 실행하면 모든 시간 창을 가져 오는 것을 의미합니다. 맞습니까?! 글쎄, 그것이 맞다면 사실 더 악화 되겠지요 :-) – Rafid

+0

SQL에서는 한 문장을 실행하고 모든 DELETE * FROM TimeWindows WHERE EntryId = ...와 같은 모든 시간 창을 삭제할 수 있습니다. 그래서 Entity Framework에서 동일한 것이 가능합니까? – Rafid

+0

ToList를 실행하면 데이터를 한 번만 가져옵니다. 배치 삭제는 [작은 해킹] 없이는 불가능합니다 (http://stackoverflow.com/questions/9776964/what-is-the-recommended-practice-to-update-or-delete-multiple-entities-inentent/9777017). # 9777017)하지만이 접근 방식을 사용할 때 데이터베이스에서 수행 된 변경 사항은 컨텍스트에 반영되지 않습니다. –