2016-10-05 6 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 Postがあります。ブログと投稿の間には1対多の関係があります。

私は次のことを行うことができます。もちろん、ブログ

からすべての投稿を削除するとします:

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

ただし、以下は簡単に思える:

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

しかし、このリードInvalidOperationException:

操作が失敗しました:1つ以上の外部キーのプロパティがnull値ではないため、関係を変更できませんでした。リレーションシップが変更されると、関連する外部キー・プロパティーはNULL値に設定されます。外部キーがNULL値をサポートしていない場合は、新しい関係を定義する必要があります。また、外部キー・プロパティーに別の非NULL値を割り当てる必要があります。

コレクションをクリアする適切な方法は何ですか?これに流暢なAPIステートメントがありますか?

+0

は、私の知る限りでは、残念ながら* .Remove()*または* .RemoveRange()*使用する以外に方法はありませんBlog.Postsコレクションから投稿を削除します。もちろん、EFを介してSQLを直接実行する以外は、その点を逃してしまうと思います。 – Robert

+0

あなたのケースについては、こちらをご覧ください:http://stackoverflow.com/a/6181060/6804888モデルを変更せずに、エンティティをコレクションから削除した後、手動で削除する必要があると考えられます。 – kiziu

答えて

1

Clearは関係に作用し、エンティティの削除には作用しません。

あなたが書いた2つのソリューションの間には、(わかりやすく)半分の解決策があります。

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

EDITは
RemoveRange

+0

本当にコレクションをクリアしてすべての要素を削除したい場合は(この質問のように、このソリューションは最も読みやすいですが)、元のメソッドを作成したいブログのIDだけを持っていれば、 –

0

2つのコードサンプルに違いがあります。

最初のコードサンプルdbContext.RemoveRange(postsToRemove)は、Postレコードを削除します。そのため、これらのレコードを含む関係も削除されます。

myBlog.Posts.Clear()の2番目のコードサンプルでは、​​myBlogと対応するPostレコードの関係を削除しています。 「実際の」根底にあるアクションは、PostレコードのBlogIdの値をnullに設定することです。残念ながら、これは可能ではありません。BlogIdがnullに設定されていないためです。要するに、関係は削除され、レコードは実際には削除されません。

+0

あなたは正しいです。私はなぜこの方法を選ぶのか理解しています。コレクションがクリアされたときにアイテムを削除する例は望ましくありません。 –

関連する問題