Entity Framework - Doublon dans la DB - C#/.NET managed - Programmation
Marsh Posté le 13-10-2015 à 13:54:36
La question est : comment tu lis ton type existant et ton nouveau contact dans ton code.
Commence par montrer comment tu écris dans ta base, je ne vois pas comment on pourrait t'aider à corriger ton code sans le voir ...
Marsh Posté le 14-10-2015 à 16:15:46
C'est basé en grande partie sur cette DAL:
http://dotnetspeak.com/2013/03/vs- [...] as-vegas-2
Mais je crois que je viens de comprendre d'où viens le problème, et ça me fout les boules.
Je ne sais pas pourquoi sur sa démo à lui en EF5 ca marche, alors que moi en EF6 ça ne marche pas, alors que je n'ai pas fait de grosse différence au niveau du code.
Je me rends compte en fait que dès qu'on associe un objet à un autre, il faut obligatoirement le faire au sain d'un context. (using...).
Si les objets sont associés en-dehors du context ou dans 2 context différents, le lien ne se fait pas correctement.
Mais du coup comment on fait pour ne pas utiliser de context dans la couche Business???
Marsh Posté le 14-10-2015 à 16:17:26
Je ne comprend pas la moitié de ce que tu dis.
On veut voir TON code, la partie utile. Vu ton use case décrit au début ça ne doit pas faire plus de 30 lignes.
Marsh Posté le 14-10-2015 à 16:22:21
Il y a une vingtaine de classes et dizaine d'interfaces pour la DAL... alors bon...
Marsh Posté le 14-10-2015 à 16:39:12
Y a pas 50000 façons de charger ou désigner une entité existante par son id, pour la lier à une autre et déclencher la persistance.
C'est ça dont on a besoin pour t'aider, pas du brol autour.
Perso là j'ai pas trop envie de debugger 16,5Mo de sources d'un autre qui ne posent même pas le problème que tu espères nous voir résoudre...
Marsh Posté le 14-10-2015 à 18:09:42
Bon okay.
Alors dans la couche Access layer, pour tous ce qui est d'opération d'écriture il y a cette classe abstraite "WriteRepository":
Code :
|
Elle est abstraite, générique et est implémentée par tous les classes repositories. Exemple celle des catégories:
Code :
|
Comme tu le vois cette classe repository dispose de méthodes permettant de charger des objets présents en db.
Au dessus de tout ça, il y la couche Business qui dispose de classes de service. Ces classes de service sont instanciées à l'aide de StructureMap pour une meilleure isolation entre les couches. Mais rien de spécial de ce côté elles ne font que faire appel aux méthodes des classes repository correspondantes.
Bref en gros l'opération que j'exécute pour vérifier si l'association entre l'object "Contact" et l'objet "Category" se fait bien est la suivante:
Code :
|
Résultat, la cat est présente 2 fois en db.
Alors que si je n'utilise pas la DAL, et que j'utilise le classique:
Code :
|
Et que j’effectue les opérations dedans, ça marche correctement.
Alors il y a bien la méthode "Attache" du context qui permet justement de rattacher un objet déconnecté du context. Mais ça fait limite usine à case par la suite.
Il y a aussi la méthode "AddOrUpdate", mais elle effectue une opération de lecture en db à chaque fois pour vérifier si l'objet est bien présent ou pas, bref usine à gaz aussi.
Marsh Posté le 15-10-2015 à 09:10:41
Au début de ton code tu as déjà ta catégorie en base, ou bien tu en as 0 ?
Si elle existe déjà et que Name sur catégorie n'est pas ta PK comment tu veux que le système comprenne qu'il doit prendre celle qui existe et pas en générer une nouvelle ?
Pour lui tu es bien en train de chercher à créer une nouvelle catégorie. Pour attacher une existante il faut la charger par son id, ou bien écrire directement dans le champ FK_Categorie de Contact.
Si par contre tu dis que ce code là te génère 2 catégories alors que tu en avais 0, je ne sais quoi te dire.
Marsh Posté le 15-10-2015 à 11:46:02
La méthode "CreateCategory" en ligne 3, crée justement l'objet en base de donnée.
Avant cette ligne son id est bien évidemment 0, après le CreateCategory l'id est bien incrémenté.
Mais même sans créer l'objet, par exemple en utilisant à la place la ligne 5 en commentaire "catService.GetCategory(1);", un objet existant en db est chargé au lieu de le créer, pourtant le problème est le même.
Marsh Posté le 15-10-2015 à 12:25:04
fredo3 a écrit :
|
C'est pas clair pour moi
T'es en train de me dire qu'en liant cette instance d'objet chargé depuis la base à ton contact tu te retrouves avec une nouvelle catégorie ? Et avec un id différent dans ce cas ?
pas possible
Marsh Posté le 15-10-2015 à 12:27:40
Après sauvegarde du contact, oui c'est ça
En gros j'associe au contact la catégorie qui a un ID = 1. Je sauvegarde le contact, et il se retrouve avec une catégorie avec ID = 2 .
Marsh Posté le 15-10-2015 à 14:11:21
Poste le code de la version qui est sensé faire ça avec le GetCategory(1).
Marsh Posté le 26-10-2015 à 16:49:20
J'ai pas tout compris non plus.
Je soupçonne que tu essaies d'assigner un objet Type à ton Contact au lieu d'assigner uniquement l'ID. (j'ai plus fait d'EF depuis 11 mois mais il me semble que j'avais fait une erreur similaire au tout début )
Genre:
Code :
|
au lieu de
Code :
|
Marsh Posté le 10-10-2015 à 14:33:59
Bonjour
J'essaye de me faire un peu la main sur Entity Framkework. l'API a un comportement pour le moins bizarre, ou du moins que je ne comprends pas. Du coup je me demande si je ne me serais pas trompé quelque part.
J'explique.
Imaginez que vous ayez une entity "Contact" et une "Type". Un contact peut avoir un type. Et un type peut être associé à plusieurs contacts, forcément.
Alors ce que je ne comprends pas c'est que quand j'associe un objet "contact" avec un objet "type" déjà présent en db (bref qui a déjà un id), EF injecte un contact en base de donnés, très bien, sauf qu'en même temps il me réinjecte un nouveau objet "Type" en base de donnés aussi (alors qu'il y est déjà présent!).
Je me suis trompé quelque part dans la config du bazar?
Merci