Je ne parviens pas à supprimer les lignes associées dans Entity Framework 4.1. J'ai des tables avec des relations
Livre 1 <---> * BookFormats
J'ai mis la cascade sur supprimer:
ALTER TABLE [dbo].[BookFormats] WITH CHECK ADD CONSTRAINT [FK_BookFormats_Book]
FOREIGN KEY([BookID]) REFERENCES [dbo].[Book] ([BookID]) on delete cascade
La propriété EDMX
Ensuite, je souhaite supprimer tous les éléments BokFormats
liés à mon objet Book
:
var originalBook = m.db.Book.First(x => x.BookID == bookId);
originalBook.BookFormats.Clear();
m.db.SaveChanges();
Mais j'ai l'erreur:
L'opération a échoué: la relation n'a pas pu être modifiée car une ou plusieurs des propriétés de clé étrangère ne sont pas nullables. Lorsqu'un une modification est apportée à une relation, la propriété de clé étrangère associée est mis à une valeur nulle. Si la clé étrangère ne supporte pas les valeurs NULL, une nouvelle relation doit être définie, la propriété de clé étrangère doit être attribué une autre valeur non nulle, ou l'objet non lié doit être supprimé.
J'ai manqué d'idées sur la façon de supprimer ces objets. Des idées?
Le concept de suppression en cascade est le suivant:
Lorsque vous supprimez Book
de la base de données, tous les BookFormats
liés seront supprimés pour vous par SQL Server (veuillez noter que la suppression de Book
n'a pas d'importance, elle sera lancée via EF ou SQL brut). Cela n'a donc rien à voir avec votre tâche: "Je veux supprimer tous les BookFormats
liés à mon Book
". Pour ce faire, vous avez besoin de quelque chose comme ceci:
foreach(var m in m.db.BookFormats.Where(f=>f.BookID == bookID))
{
m.db.BookFormats.Remove(m);
}
m.db.SaveChanges();
Vous pouvez utiliser RemoveRange:
m.db.BookFormats.RemoveRange(originalBook.BookFormats);
m.db.SaveChanges();
Mais ceci est pour EF 6.0
Vous ne supprimez pas la BookFormats
de la base de données, mais vous supprimez la relation. Vous définissez ainsi votre BookFormats
et définissez la colonne BookID
surNULL. La cascade de suppression que vous avez mise dans la base de données indique When I delete the
Book, then delete all of the
BookFormatsthat have a
BookIDequal to mine.
Vous ne supprimez pas le livre que vous supprimez des formats de la Book
.
Au lieu de originalBook.BookFormats.Clear()
, vous devriez avoir quelque chose comme ça ...
List<int> idsToDelete = new List<int>();
foreach (BookFormat bf in originalBook.BookFormats)
{
idsToDelete.Add(bf.ID);
}
foreach (int id in idsToDelete)
{
BookFormat format = m.db.BookFormat.FirstOrDefault(x => x.ID == id);
if (format != null)
{
m.db.DeleteBookFormat(format);
}
}
m.db.SaveChanges();
Ce devrait être quelque chose dans ce sens. Je n'ai pas le droit de me rappeler comment EF construit la méthode de suppression dans EDMX.
Je l'ai testé dans EF 6.1.3 et cela devrait fonctionner correctement:
var originalBook = m.db.Book.First(x => x.BookID == bookId);
originalBook.BookFormats.Clear();
db.Books.Remove(originalBook);
m.db.SaveChanges();
J'utilise EF6 et cela fonctionne.
var itemBinding = db.ItemBinding.Where(x => x.BindingToId == id) ;
foreach (var ib in itemBinding)
{
db.Item.Remove(ib.Item);
db.ItemBinding.Remove(ib);
}
db.SaveChanges();