IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Entity Framework Discussion :

Generer un code client unique


Sujet :

Entity Framework

  1. #1
    Membre régulier

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    165
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2003
    Messages : 165
    Points : 95
    Points
    95
    Par défaut Generer un code client unique
    Bonjour,

    Je dois générer un code client unique pour une entité de client avec entity framework. Problème je peux pas faire des bidouilles genre un trigger dans la base, je dois utiliser la couche métier entity. Comment dire à entity, par exemple génère moi un nombre unique (ou même à la limite recopie l'id de l'entité dans ce champs s'il est vide).

    Je ne peux pas faire deux sauvegardes (genre sauver l'entité, récupérer son id donné par la base et refaire une sauvegarde de se nombre dans "code client", faudrait tout faire en une fois).

    Ce n'est pas un id de la table mais bien un autre champ.

    Merci de vous conseilles

  2. #2
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Utiliser les GUID : ça assure l'unicité et la complétude d'un objet avant sa persistence.

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  3. #3
    Membre régulier

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    165
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2003
    Messages : 165
    Points : 95
    Points
    95
    Par défaut
    oui mais non, là je dois prendre un numéro car ça doit pouvoir être synchronisé avec d'autre système qui vont mettre cette élément comme clé dans un champ int.

    Mais merci j'ai utilisé ça pour un autre système.

    Sinon j'ai pensé utiliser Timer.Tick mais ça fait un numéro vachement long...

  4. #4
    Membre chevronné Avatar de Er3van
    Homme Profil pro
    Architecte Logiciel
    Inscrit en
    Avril 2008
    Messages
    1 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte Logiciel
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2008
    Messages : 1 430
    Points : 2 227
    Points
    2 227
    Par défaut
    Si tu veux de l'unicité c'est forcément quelque chose d'assez long.... sauf si tu peux réduire le scope de l'unicité.
    Par exemple, si tu sais qu'il ne peut jamais il y avoir deux opérations similaire dans la même minutre, tu peux juste prendre yyMMdd-HHmmss...
    One minute was enough, Tyler said, a person had to work hard for it, but a minute of perfection was worth the effort. A moment was the most you could ever expect from perfection.

    -- Chuck Palahniuk, Fight Club, Chapter 3 --

  5. #5
    Membre régulier

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    165
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2003
    Messages : 165
    Points : 95
    Points
    95
    Par défaut
    est ce qu'il y a une règle pour mettre un champs dans un autre plutôt?

    est ce qu'on peut simuler des triggers mais dans entity?

    je devrais mettre "une valeur + id" dans ce champs.

    Merci

  6. #6
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par Husqvarna Voir le message
    est ce qu'il y a une règle pour mettre un champs dans un autre plutôt?


    est ce qu'on peut simuler des triggers mais dans entity?
    Là encore, je ne comprends pas bien ... le trigger étant quelque chose de spécifiques aux base de données, ta demande n''est pas bien claire.

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  7. #7
    Membre régulier

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    165
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2003
    Messages : 165
    Points : 95
    Points
    95
    Par défaut
    c'est pour cela que je dis simuler...

    Ok le problème est que j'ai un champs que je dois remplir de manière unique avec un int, mais que je peux pas me vaser sur les contraintes de base de données.

    Est ce que j'ai un moyen d'incrémenter un int sur l'application server en étant certaine de son unicité?

  8. #8
    Invité
    Invité(e)
    Par défaut


    Pour simuler un Trigger (insert, update ou delete) il faut que tu t'abonnes à l'évènement SavingChanges de ton contexte. À partir du gestionnaire de l'évènement tu pourras récupérer les entités qui sont en phase d'être mises à jour, d'être insérées, ou d'être supprimées. Dans ton cas à toi, tu as juste besoin de récupérer les entités type client qui sont en phase d'insertions, donc tu dois te te baser sur la propriété ObjectStateManagement de ton contexte et sur l'état Added de tes entités (j'ai fourni récemment un exemple via cette discussion) pour récupéer les nouveaux clients. Une fois que tu as la liste tu la parcours pour attribuer à chacun un numéro UNIQUE (si c'est une clef primaire de ta base de données ou s'il y a une contrainte d'unicité définie).

  9. #9
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par Husqvarna Voir le message
    Est ce que j'ai un moyen d'incrémenter un int sur l'application server en étant certaine de son unicité?
    Le problème est que tu ne précises pas l'étendue (spatiale et temporelle) de l'unicité que tu souhaites; donc il est difficile de te donner une réponse.

    La seule manière d'avoir une unicité spatiale et temporelle "absolue" (tout est relatif) sont les GUID; tu ne veux pas utiliser cette solution; ok, mais dans ce cas donne nous l'étendu de l'unicité que tu veux avoir :

    - illimité temporellement mais spatialement local à la base (auquel cas, il suffit d'avoir une table avec une colonne et une ligne incrémentée que tu interroges quand tu veux récupérer un int unique).

    - illimité temporellement et spatialement : impossible sans les GUID.

    - limitée temporellement et spatialement : un compteur dans l'instance serveur fait l'affaire.

    Donc, précise ce que tu souhaites, et on y verra plus clair.

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  10. #10
    Membre régulier

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    165
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2003
    Messages : 165
    Points : 95
    Points
    95
    Par défaut
    Citation Envoyé par h2s84 Voir le message


    Pour simuler un Trigger (insert, update ou delete) il faut que tu t'abonnes à l'évènement SavingChanges de ton contexte. À partir du gestionnaire de l'évènement tu pourras récupérer les entités qui sont en phase d'être mises à jour, d'être insérées, ou d'être supprimées. Dans ton cas à toi, tu as juste besoin de récupérer les entités type client qui sont en phase d'insertions, donc tu dois te te baser sur la propriété ObjectStateManagement de ton contexte et sur l'état Added de tes entités (j'ai fourni récemment un exemple via cette discussion) pour récupéer les nouveaux clients. Une fois que tu as la liste tu la parcours pour attribuer à chacun un numéro UNIQUE (si c'est une clef primaire de ta base de données ou s'il y a une contrainte d'unicité définie).
    Hello merci de la réponse.

    C'est exactement ce que je fais mais au CREATE, j'ai pas d'id unique (car pas encore créé dans la base), y a "0" comme valeur. Et après la sauvegarde c'est trop tard... c'est pour ça que j'ai parlé de trigger simulé...

  11. #11
    Membre régulier

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    165
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2003
    Messages : 165
    Points : 95
    Points
    95
    Par défaut
    - limitée temporellement et spatialement : un compteur dans l'instance serveur fait l'affaire.
    Merci pour ton message.

    Oui cela serait bien mais tu gère cela comment, il doit être sauvegardé si on redémarre le serveur tu l'écris dans le fichier de config? je vais pas rajouter une table dans la db pour lui quand même?
    Et on est certain de pouvoir faire un véritable singleton avec ces histoires d'asynchrone...

  12. #12
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Husqvarna Voir le message
    C'est exactement ce que je fais mais au CREATE, j'ai pas d'id unique (car pas encore créé dans la base), y a "0" comme valeur. Et après la sauvegarde c'est trop tard... c'est pour ça que j'ai parlé de trigger simulé...
    À ce que j'ai compris, c'est ta base de données qui gère la génération de l'ID. Donc normalement si ton Modèle EDMX est généré à partir de ta base de données alors EF le détectera automatiquement et mettra la propriété StoreGeneratedPattern de la colonne concernée à Computed ou Identity dans la partie SSDL. Du coup à chaque insertion d'une nouvelle entité EF renverra les valeurs de chaque colonne dont les valeurs sont gérées par ta base de données.

    Si après chaque insertion d'un client tu te retrouves avec 0 comme ID cela veut dire que ton EDMX plus particulièrement ton SSDL n'est pas bien configuré. Pour pouvoir récupérer le dernier ID inséré, ouvre le fichier EDMX au format XML, localise dans la partie SSDL, la colonne ID de l'entité client et rajoute la propriété StoreGeneratedPattern="Computed" .

    Bref plus d'infos ici.

  13. #13
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par Husqvarna Voir le message
    Merci pour ton message.

    Oui cela serait bien mais tu gère cela comment, il doit être sauvegardé si on redémarre le serveur tu l'écris dans le fichier de config? je vais pas rajouter une table dans la db pour lui quand même?
    Et on est certain de pouvoir faire un véritable singleton avec ces histoires d'asynchrone...
    C'est pour cela que je parlais de limitation temporelle. Si tu dois le persister fais le dans la base.

    Le sauver dans le fichier de config me semble une idée plus que curieuse: il n'est pas certain que les serveurs applicatifs soient sauvegardés quotidiennement (vu leur faible "variabilité") alosr que les serveurs de DB le sont. (en général .....).

    Donc autant persister le compteur dans la base, qui est l'endroit par excellence pour persister des données ! (et c'est pas le cas du tout du fichier de config).

    Tout autre solution me semble créer une complication opérationelle sans la moindre justfication ni le moindre bénéfice.

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  14. #14
    Membre chevronné Avatar de Er3van
    Homme Profil pro
    Architecte Logiciel
    Inscrit en
    Avril 2008
    Messages
    1 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte Logiciel
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2008
    Messages : 1 430
    Points : 2 227
    Points
    2 227
    Par défaut
    Ceci dit, c'est une remarque en l'air hein, mais si tu fais quelque chose comme "select max(clientId)" + random.Next(1,100), tu auras très peu de chance de tomber sur le cas où tes deux nombres sont identiques...
    Pis si c'est le cas, tu peux faire une reprise en exception

    Cependant, si l'unicité est vraiment cruciale, les méthodes citées ci-dessous devraient en effet te permettre de solutionner cette problématique...
    One minute was enough, Tyler said, a person had to work hard for it, but a minute of perfection was worth the effort. A moment was the most you could ever expect from perfection.

    -- Chuck Palahniuk, Fight Club, Chapter 3 --

  15. #15
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Points : 1 257
    Points
    1 257
    Par défaut
    Une colone nullable "ClientIdentifier" FK vers une table "ClientIdentifier" qui ne contient qu'une colonne Id de type "int" autoinc.

    et en EF quand tu veux créer un idclient sur ton objet tu fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    monObjet.ClientIdentifier= new ClientIdentifier()
    context.SaveChanges()
    //Ton id est la et il est unique de type int
    monObjet.ClientIdentifier.Id
    //Ou dans une colone directement mappé
    monObjet.ClientIdentifierId

Discussions similaires

  1. generer son code client sous firebird ?
    Par BXDSPORT dans le forum Bases de données
    Réponses: 12
    Dernier message: 14/12/2009, 15h16
  2. Réponses: 3
    Dernier message: 29/01/2008, 09h51
  3. Réponses: 44
    Dernier message: 02/08/2006, 16h12
  4. Réponses: 2
    Dernier message: 27/04/2006, 16h45
  5. [C#] Comment générer le code à partir du WSDL ?
    Par Piolet dans le forum Services Web
    Réponses: 2
    Dernier message: 27/08/2004, 13h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo