Entity Framework, AutoMapper, la manipulation de l'entité mises à jour
J'ai juste commencé à l'aide de Entity Framework 1.0 récemment et je crois que je suis commence à sentir les douleurs de tout le monde en parle. Je suis en train d'utiliser les meilleures pratiques donc, j'ai un ensemble de DTO obtenir mappé à partir de mes Entités via AutoMapper.
Le vrai catch, c'est quand je suis en train de mettre à jour un objet. Le premier piège est que je ne pouvais pas trouver un moyen de créer une nouvelle entité, transférer les données de mon DTO, et ont encore de l'entité ObjectContext rends compte qu'il a été modifié. J'ai utilisé le code suivant:
public VideoDTO UpdateVideo(VideoDTO pVideo)
{
Video video = new Video();
Mapper.Map(pVideo, video);
context.Attach(video); //Successfully attaches
context.ApplyPropertyChanges("Videos", video); //no changes made as far as entity knows b/c it was attached in it's updated state
context.SaveChanges(); //doesn't save the entity
return pVideo;
}
J'ai alors pensé que, peut-être que j'ai juste besoin de saisir l'entité de la base de données tout d'abord, fixez le contexte, l'appel de la méthode Map sur Mapper, puis appelez SaveChanges. Voici ce que j'ai fait:
public VideoDTO UpdateVideo(VideoDTO pVideo)
{
Video video = context.Videos.Where(v => v.VideoId == pVideo.VideoId).FirstOrDefault();
Mapper.Map(pVideo, video); //Error here: Can't change VideoId value on Video entity
//context.Attach(video);
//context.ApplyPropertyChanges("Videos", video);
context.SaveChanges();
return pVideo;
}
Maintenant nous arrivons à la belle EF question de ne pas être autorisé à modifier la propriété, VideoId, car il est utilisé par le EntityKey bien sur la Vidéo de l'entité. Belle. J'ai eu de configuration des mappages de sorte que lorsque j'ai mappé à partir de mon DTO à une EF Entité, la EntityKey propriété serait d'obtenir une valeur. Maintenant j'ai besoin d'un moyen de faire une exception à la règle de mappage, mais n'avez aucune idée de par où commencer. Je suppose que je pourrais créer une nouvelle marque de Cartographie de la règle de droit dans cette méthode et de définir la EntityKey & VideoId propriétés pour être ignoré, mais qui semble assez bâclée. En outre, je ne suis pas sûr de cartographie créé à ce stade de bâton. Si elle l'emportait sur la configuration initiale qui a permis à la DTO de carte d'une valeur à la EntityKey sur l'entité, qui pourrait se retourner contre nous dans une toute autre manière.
Que quelqu'un a une meilleure idée?
OriginalL'auteur jason | 2010-01-29
Vous devez vous connecter pour publier un commentaire.
AutoMapper
Votre premier problème est que tant que je sais AutoMapper n'est pas conçu pour aller de DTO->Entité que l'Entité->DTO. Ce qui pourrait avoir changé récemment, donc je ne suis pas vraiment sûr. Voir ce lien pour plus d'informations sur ce automapper est conçu pour faire: Le cas pour les deux sens de cartographie
PK Cartographie
Vous dites: "Cartographie de la règle de droit dans cette méthode et de définir la EntityKey & VideoId propriétés pour être ignoré, mais qui semble assez bâclée"
Je ne pense pas que c'est bâclé. Vous ne devriez vraiment pas toucher un EntityKey/PK après son persisté et probablement devrait codifier ses staticness d'une certaine façon.
Entity Framework
"Nous en arrivons maintenant à la belle EF question de ne pas être autorisé à modifier la propriété, VideoId, car il est utilisé par le EntityKey bien sur la Vidéo de l'entité. Belle."
Belle? EF n'est pas de vous forcer à ne pas mettre à jour votre PK. À l'intérieur de l'généré des modèles il y a un changement de propriété vérifiez à l'intérieur de l'incubateur pour vos clés. La solution serait de modifier le code généré. Selon votre modèle de volatilité que cela peut ne pas être pratique, mais c'est une option.
Ok, vous avez mentionné que Automapper n'était pas destinée à aller de DTO --> EF Entité, mais a été conçu pour être EF -> DTO. Si c'était le cas, comment suis-je censé mettre à jour ma base de données via EF objets lorsque les objets utilisés dans mon point de vue et le contrôleur sont DTO objets? Je n'essaie pas d'être condescendant ou quoi que ce soit. J'essaie juste de trouver la bonne façon de gérer les insertions et mises à jour, tandis que de ne pas encombrer ma demande pour un accès des données spécifiques de mise en œuvre. Je suis ouvert à toutes les suggestions que vous pourriez avoir.
Autant que je sache = autant que je sais, désolé de ne pas être plus clair
Je cherchais sur mes questions ouvertes et ont vu celle-ci. Après lecture de votre réponse ET le lien de l'article (RTFM...je sais...), les choses prennent beaucoup plus de sens. C'était en fait plutôt de libérer à la force de mon DTO est de simplement imiter les conventions mandaté par mon modèle de Domaine. Je me rends compte qu'il y a beaucoup de remplissage, j'ai été mise en eux que juste n'a pas besoin d'être là. Merci pour la réponse informative. Désolé, il m'a fallu ce temps "get it".
OriginalL'auteur John Farrell
Essayez d'associer à un objet existant:
Et de garder l'Ignore()'s en place.
http://groups.google.com/group/automapper-users/browse_thread/thread/24a90f22323a27bc?fwc=1&pli=1
OriginalL'auteur ishakkulekci
Cela peut être utile si vous voulez éviter de mettre
.Ignore()
s sur chaque Entité que vous souhaitez Mapper.http://www.prosoftnearshore.com/blog/post/2012/03/14/Using-AutoMapper-to-update-Entity-Framework-properties.aspx
En essence, vous souhaitez configurer AutoMapper à ignorer toutes les propriétés d'Entité qui ne sont pas scalaire:
Peut-être un travail supplémentaire peut être ajouté pour éviter la réinitialisation si la propriété est un PK (une propriété dans le
EdmScalarPropertyAttribute
instance (EntityKey == true?
) vous dit cela).OriginalL'auteur Mauricio Morales
Je suis dans le même scénario.
La seule solution que j'ai est d'Ignorer le PK champ de la cartographie de DTO -> Entité.
Une telle Règle peut être atteint par la ligne de code suivante au cours de l'Automapper Configuration:
Autant que je sache, la seule façon d'obtenir EF fonctionne avec du recul des Entités est la cartographie de la DTO de l'Entité que vous avez obtenu à partir de DB avant la SaveChanges (comme vous l'avez fait dans l'exemple).
OriginalL'auteur Bitbreaker
S'il vous plaît être conscient que l'exemple fourni par "Mauricio Morales" ne fonctionne que si vous n'utilisez pas de préfixes. Si vous les utilisez alors vous avez besoin de changer le code ci-dessus légèrement de plus ou moins comme ceci:
Qui est, vous avez besoin d'inclure des vérifications supplémentaires à l'intérieur de
if (!members.Any())
déclaration. Sans cela, la fonction retourne false et la cartographie ne fonctionnera pas.OriginalL'auteur Mariusz Gorzoch