11
votes

Mappage d'une DTO à une entité avec FABORAPPER

J'ai un cadre d'entité poco avec la structure suivante.

public ActionResult EditEntity(EntityDto model)
{
    var entity = context.Entities.Single(e => e.Id == model.Id);
    entity = Mapper.Map<EntityDto, Entity>(model); // this loses the Entity Key stuff
    context.SaveChanges();

    return View(model);
}


0 commentaires

3 Réponses :


19
votes

Essayez d'utiliser une entité de passage comme deuxième paramètre à votre mappage. XXX

Sinon, votre instance d'entité est écrasée avec une nouvelle instance et que vous perdez l'entité créée dans la première ligne.


7 commentaires

Malheureusement, j'ai déjà essayé cela, provoque le même problème - essentiellement automapper dit qu'il ne trouve pas de configuration de mappage comme lorsque j'ai récupéré mon entité du contexte, ce n'est plus votre POCO moyen et ainsi Automapper ne sait pas quoi faire.


S'il y a d'autres propriétés sur l'entité que vous n'avez pas répertoriées, vous pouvez aussi bien vouloir dire que Coorapper de les ignorer: .Formember (DEST => DEST.PROPERTYTOITEMORE, OPT => OPT.UtilisationValue)


C'est le problème, à l'époque je crée mes mappages automapper entité est juste un poco, donc ne contient aucune des choses d'entité supplémentaire que EF crée lors de la récupération, donc je ne peux pas Dites à Comtableapper de les ignorer.


Bien que l'entité renvoyée sur la première ligne n'est pas d'une entité de type, survolez «Var» et voyez quel type il s'agit et créez un mappage pour ce type. En outre, c'est la deuxième cartographie entité> dont vous avez besoin, pas le premier


Saint Crud Je ne savais pas que vous pourriez le faire avec une carte. Incroyable.


Attendez, cela ne signifie-t-il pas que si l'entitédto est un sous-ensemble d'entité (ce qui est presque toujours), il échouera alors le test d'affirmation?


@dark_Ruby merci beaucoup, ça résume mon problème



10
votes

.attach () mon entité mappée et définissez l'état à modifier? p>

public ActionResult EditEntity(EntityDto model)
{
    using(var context = new MyContext())
    {
        var entity = Mapper.Map<Entity>(model);
        context.Set<Entity>().Attach(entity); // (or context.Entity.Attach(entity);)
        context.Entry<Entity>(entity).State = System.Data.EntityState.Modified;
        context.SaveChanges();
        return View(model);
    }
}

3 commentaires

Brillant, cela vient de travailler. Donnez-moi quelques instants pour essayer mon projet actuel.


Je suis content de pouvoir alt-tab et de copier la pâte. Je veux dire vous aider. :)


Vous ne devriez pas utiliser les entités EF directement dans le calque de présentation, il s'agit d'un exemple classique de la manière de ne pas séparer vos préoccupations.



3
votes

une réponse alternative qui ne nécessite pas que STOCAPPER pour la conversion d'entité DTO utilise une dbentry:

        var oldEntity = DbSet.FirstOrDefault(x => x.Id == updatedEntity.Id);
        var oldEntry = Context.Entry(oldEntity);

        oldEntry.CurrentValues.SetValues(updatedEntity);


2 commentaires

Cela a totalement travaillé pour moi. La solution MAPPER.MAP (Model, Entity) n'a pas fonctionné pour moi, car lorsque vous avez une entité imbriquée, que vous mettez à jour (votre propriété fait donc référence à une entité différente (déjà suivie) maintenant), la solution automapper "écrase" L'entité précédemment référencée, et le Changetracker se plaint de suivre déjà une entité avec cet identifiant.


C'est ce qui se passe lorsque votre EF saigne dans la couche de présentation.