2016-10-05 8 views
2

Clear()를 사용하여 엔티티 프레임 워크의 컬렉션에서 모든 요소를 ​​제거하는 데 문제가 있습니다.Entity Framework ICollection의 모든 요소를 ​​지우는 방법()?

블로그 및 게시물에서 자주 사용되는 예제를 생각해보십시오.

public class Blog 
{ 
    public int Id {get; set;} 
    public string Name {get; set;} 
    public virtual ICollection<Post> Posts { get; set; } 
} 

public class Post 
{ 
    public int Id { get; set; } 

    // foreign key to Blog: 
    public int BlogId { get; set; } 
    public virtual Blog Blog { get; set; } 

    public string Title { get; set; } 
    public string Text { get; set; } 
} 

public class BlogContext : DbContext 
{ 
    public DbSet<Blog> Blogs {get; set;} 
    public DbSet<Post> Posts {get; set;} 
} 

블로그에 여러 개의 게시물이 있습니다. 블로그에는 ICollection of Posts가 있습니다. 블로그와 게시물 사이에는 일대 다의 관계가 있습니다.

Blog myBlog = ... 
myBlog.Posts.Clear(); 
dbContext.SaveChanges(); 

그러나이 리드 : 그러나

Blog myBlog = ... 
var postsToRemove = dbContext.Posts.Where(post => post.BlogId == myBlog.Id); 
dbContext.RemoveRange(postsToRemove); 
dbContext.SaveChanges(); 

가, 다음이 쉽게 보인다

가정하자 나는 물론

다음 작업을 수행 할 수있는 블로그의 모든 게시물을 제거하려면 InvalidOperationException :

operation failed : 하나 이상의 foreign-key 속성이 nullable이 아니기 때문에 관계를 변경할 수 없습니다. 관계가 변경되면 관련 외래 키 등록 정보는 널 (NULL) 값으로 설정됩니다. 외부 키가 널값을 지원하지 않으면, 새 관계가 정의되어야하고, 외부 키 등록 정보에 널이 아닌 다른 값이 지정되어야합니다. 그렇지 않으면 관련이없는 오브젝트가 h 제되어야합니다.

컬렉션을 지우는 적절한 방법은 무엇입니까? 이것을위한 유창한 API 성명서가 있습니까?

+0

는 지금까지 내가 아는 한, 불행하게도 * .Remove() * 또는 * .RemoveRange() * 사용하는 것보다 다른 방법이없는 Blog.Posts 컬렉션에서 게시물을 제거합니다. 물론 EF를 통해 SQL을 직접 실행하는 것 이외에도 요점을 놓치고 있다고 생각합니다. – Robert

+0

사례는 여기에 설명되어 있습니다. http://stackoverflow.com/a/6181060/6804888. 모델을 변경하지 않고 엔티티를 컬렉션에서 제거한 후 엔티티를 수동으로 삭제해야합니다. – kiziu

답변

1

Clear은 엔티티를 삭제하는 것이 아니라 관계에 적용됩니다.

작성한 두 가지 솔루션 사이에서 작동하는 (생각보다 읽기 쉽습니다) 절반 방법 솔루션이 있습니다.

dbContext.Posts.RemoveRange(myBlog.Posts); 
// Now (also before SaveChanges) the myBlog.Posts is empty 
dbContext.SaveChanges(); 

편집
RemoveRange 또한

+0

정말로 컬렉션을 지우고 모든 요소를 ​​제거하려는 경우 (이 솔루션은 가장 읽기 쉽습니다.) 그러나 원본 메소드를 작성하려는 블로그의 ID 만 가지고 있으면 블로그를 먼저 저장하는 것이 좋습니다 –

0

두 코드 샘플간에 차이점이 있습니다.

첫 번째 코드 샘플 dbContext.RemoveRange(postsToRemove)Post 레코드를 제거합니다. 따라서이 기록과 관련된 모든 관계도 제거됩니다.

두 번째 코드 샘플 myBlog.Posts.Clear()에서 myBlog과 해당하는 Post 레코드 간의 관계를 제거합니다. '실제'기본적인 조치는 Post 레코드의 BlogId 값을 null으로 설정하는 것입니다. 죄송하지만 BlogId이 null이 아닌 것으로 설정되어 있기 때문에 불가능합니다. 즉, 관계가 제거되고 레코드가 실제로 삭제되지 않습니다.

+0

맞습니다. 왜이 방법을 선택하는지 이해합니다.컬렉션이 지워졌을 때 항목을 삭제하는 경우는 바람직하지 않습니다. –

관련 문제