Comment supprimer un object d’un modèle Entity Framework sans le charger au préalable?

Je suis tout à fait sûr d’avoir vu la réponse à cette question quelque part, mais comme je n’ai pas pu le trouver avec quelques recherches sur SO ou Google, je le redis quand même …

Dans Entity Framework, le seul moyen de supprimer un object de données semble être

MyEntityModel ent = new MyEntityModel(); ent.DeleteObject(theObjectToDelete); ent.SaveChanges(); 

Cependant, cette approche nécessite que l’object soit chargé dans ce cas, le contrôleur d’abord, juste pour le supprimer. Existe-t-il un moyen de supprimer un object métier référençant uniquement son ID, par exemple?

S’il existe une manière plus intelligente d’utiliser les expressions Linq ou Lambda, c’est bien aussi. L’objective principal est d’éviter de charger des données simplement pour le supprimer.

Il est important de savoir que Entity Framework prend en charge à la fois les entités Linq vers Entity SQL et Entity SQL. Si vous souhaitez effectuer des suppressions ou des mises à jour susceptibles d’affecter de nombreux enregistrements, vous pouvez utiliser l’équivalent d’ ExecuteNonQuery .

Dans Entity SQL, cela pourrait ressembler à

  Using db As New HelloEfEntities Dim qStr = "Delete " & _ "FROM Employee" db.ExecuteStoreCommand(qStr) db.SaveChanges() End Using 

Dans cet exemple, db est mon ObjectContext . Notez également que la fonction ExecuteStoreCommand prend un tableau de parameters facultatif.

J’ai trouvé ce post , qui indique qu’il n’y a vraiment pas de meilleur moyen de supprimer des enregistrements. L’explication donnée était que toutes les clés étrangères, les relations, etc., qui sont uniques pour cet enregistrement, sont également supprimées. Par conséquent, EF doit avoir les informations correctes sur l’enregistrement. Je ne comprends pas pourquoi cela n’a pas pu être réalisé sans charger des données dans les deux sens, mais comme cela ne se produira pas très souvent, j’ai décidé (pour le moment) que je ne me dérangerais pas.

Si vous avez une solution à ce problème, n’hésitez pas à me le faire savoir =)

Toutes mes excuses à l’avance, mais je dois remettre en question votre objective.

Si vous supprimez un object sans jamais le lire, vous ne pouvez pas savoir si un autre utilisateur a modifié l’object entre le moment où vous avez confirmé la suppression de l’object et la suppression réelle. Dans “SQL simple vieux”, ce serait comme faire:

 DELETE FROM FOO WHERE ID = 1234 

Bien sûr, la plupart des gens ne le font pas réellement. Au lieu de cela, ils font quelque chose comme:

 DELETE FROM FOO WHERE ID = 1234 AND NAME = ?ExpectedName AND... 

Le fait est que la suppression devrait échouer (ne rien faire) si un autre utilisateur a modifié l’enregistrement dans l’intervalle.

Avec cela, une meilleure déclaration du problème, il existe deux solutions possibles lors de l’utilisation de l’entité Framework.

  1. Dans votre méthode Delete, l’instance existante, comparez les valeurs attendues des propriétés et supprimez-les si elles sont identiques. Dans ce cas, Entity Framework se chargera d’écrire une instruction DELETE qui inclut les valeurs de propriété.

  2. Ecrivez une procédure stockée qui accepte à la fois l’IDE et les autres valeurs de propriété et exécutez-la.

Il est possible de charger une entité en recalculant son EntityKey. Cela ressemble à un peu un hack, mais pourrait être la seule façon de le faire dans EF.

Article de blog sur la suppression sans récupération

Vous pouvez créer un object avec le même identifiant et le transmettre à la suppression, mais c’est bien pour les objects simples si vous avez des relations complexes, vous pourriez avoir besoin de plus que cela

  var user = new User { ID = 15 }; context.Entry(user).State = EntityState.Deleted; context.SaveChanges(); 
 var toDelete = new MyEntityModel{ GUID = guid, //or ID = id, depending on the key }; Db.MyEntityModels.Attach(toDelete); Db.MyEntityModels.DeleteObject(toDelete); Db.SaveChanges(); 

Si votre clé contient plusieurs colonnes, vous devez fournir toutes les valeurs (par exemple, GUID, columnX, columnY, etc.).

Jetez également un oeil ici pour une fonction générique si vous vous sentez pour quelque chose de chic.

Avec Entity Framework 5, il existe Entity Framework Extended Library . Disponible sur NuGet. Ensuite, vous pouvez écrire quelque chose comme:

 context.Users.Delete(u => u.Id == id); 

Il est également utile pour les suppressions en masse.