2016-10-05 1 views
2

Je rencontre des problèmes lors de la suppression de tous les éléments d'une collection dans une structure d'entité à l'aide de Clear()Comment effacer() tous les éléments d'Entity Framework ICollection?

Considérez l'exemple souvent utilisé avec les blogs et les publications.

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;} 
} 

Un blog a beaucoup de messages. Un blog a une collection de messages. Il existe une simple relation un-à-plusieurs entre les blogs et les publications.

Supposons que je veux supprimer tous les messages d'un blog

Bien sûr, je pouvais faire ce qui suit:

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

Cependant, ce qui suit semble plus facile:

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

Cependant ce qui conduit à une exception InvalidOperationException:

Échec de l'opération: La relation n'a pas pu être modifiée car une ou plusieurs des propriétés de clé étrangère sont non nullable. Lorsqu'une modification est apportée à une relation, la propriété de clé étrangère associée est définie sur une valeur nulle. Si la clé étrangère ne prend pas en charge les valeurs nulles, une nouvelle relation doit être définie, une autre valeur non nulle doit être affectée à la propriété de clé étrangère ou l'objet non lié doit être supprimé.

Quelle est la bonne façon d'effacer la collection? Existe-t-il une instruction API fluide pour cela?

+0

Pour autant que je sache, il n'y a malheureusement pas d'autre moyen que d'utiliser * .Déposer() * ou * .RemoveRange() *. Autre que de courir SQL directement via EF, bien sûr, mais cela manque le point, je pense. – Robert

+0

Votre cas est décrit ici: http://stackoverflow.com/a/6181060/6804888. Il semble que sans changer le modèle, vous devez supprimer manuellement les entités après les avoir retirées de la collection. – kiziu

Répondre

1

Clear fonctionne sur la relation et non sur la suppression de l'entité.

Il existe une solution à mi-chemin qui fonctionne (je pense plus lisible) entre les deux solutions que vous avez écrites.

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

EDIT
RemoveRange supprime également les messages de la collection Blog.Posts

+0

Si vous voulez vraiment effacer la collection et supprimer tous les éléments (comme dans la question, cette solution est la plus lisible) Cependant, si vous avez seulement l'ID du blog dont vous voulez créer les messages, la méthode originale sauve en premier –

0

Il existe une différence entre vos deux exemples de code. Le premier exemple de code dbContext.RemoveRange(postsToRemove) supprime les enregistrements Post. Par conséquent, toute relation impliquant ces enregistrements est également supprimée.

Dans votre deuxième exemple de code myBlog.Posts.Clear(), vous supprimez la relation entre myBlog et ses enregistrements Post correspondants. L'action sous-jacente «réelle» consiste à définir la valeur BlogId des enregistrements Post sur null. Malheureusement, cela n'est pas possible, car BlogId est défini sur non-nullable. Bref, la relation est supprimée et aucun enregistrement n'est supprimé.

+0

Vous avez raison.Je comprends pourquoi ils choisissent cette méthode.Il existe des exemples où la suppression des éléments lorsque la collection est effacée est indésirable. –