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

ASP.NET MVC Discussion :

Relation 0..1->1, ID se réinitialise


Sujet :

ASP.NET MVC

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif

    Homme Profil pro
    Software Developer
    Inscrit en
    Mars 2008
    Messages
    1 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Software Developer

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 470
    Par défaut Relation 0..1->1, ID se réinitialise
    Bonjour,

    Je souhaite réaliser des relations 0..1->1 mais je suis confronté a une erreur.
    Mon ID se réinitialise lors de la modification de la table.

    Mes classes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class Rent
    {
        public Guid Id { get; set; }
        public string Ref { get; private set; }
        public DateTime Availability { get; set; }
        public virtual RentPrice Price { get; set; }
    }
    public class RentPrice
    {
        [ScaffoldColumn(false)]
        public Guid Id { get; set; }
        public double Amount { get; set; }
        public RentPriceType Type { get; set; }
    }
    Controlleur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    public ActionResult Create()
    {
        return View();
    } 
     
    [HttpPost]
    public ActionResult Create(Rent rent)
    {
        if (ModelState.IsValid)
        {
            rent.Id = Guid.NewGuid();
            db.Rents.Add(rent);
            rent.Price.Id = rent.Id;
            db.SaveChanges();
            return RedirectToAction("Index");  
        }
        return View(rent);
    }
     
    public ActionResult Edit(Guid id)
    {
        var rent = db.Rents.Find(id);
        return View(rent);
    }
     
    [HttpPost]
    public ActionResult Edit(Rent rent)
    {
        if (ModelState.IsValid)
        {
            db.Entry(rent).State = EntityState.Modified;
            db.Entry(rent.Price).State = EntityState.Modified;
            db.SaveChanges();
     
            return RedirectToAction("Index");
        }
        return View(rent);
    }
    Je peux créer des données (j'ai vérifié dans la base de données et les tables Rent et Price sont bien créés avec les meme Id).
    Mais lorsque je vais a la page Edit et que je sauvegarde, j'obtiens l'erreur suivante sur la ligne db.SaveChanges(); :
    Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
    Sur la page Edit les champs de la table Price ont bien les bonnes valeurs, mais que je débogue je remarque que rent.Price.Id = "0000-0000-0000-0000" dans ma fonction Edit(Rent rent), d'ou l'impossibilité de mettre a jour un enregistrement dont l'ID n'existe pas.

    Auriez-vous une idée pourquoi l'ID de mon entité Price se réinitialise en Guid vide?

    Merci d'avance.

  2. #2
    Membre chevronné

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2011
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 244
    Par défaut
    Hello,

    Et elle ressemble à quoi la page cshtml (ou aspx) ?

  3. #3
    Membre extrêmement actif

    Homme Profil pro
    Software Developer
    Inscrit en
    Mars 2008
    Messages
    1 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Software Developer

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 470
    Par défaut
    Citation Envoyé par plume13 Voir le message
    Et elle ressemble à quoi la page cshtml (ou aspx) ?
    Merci pour ton aide.

    Ma page cshtml utilise ceci pour générer les balises de la classe RentPrice:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @Html.EditorFor(model => model.Price)
    (model.Price est de type RentPrice)

    Une idée?

  4. #4
    Membre chevronné

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2011
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 244
    Par défaut
    C'est l'attribut [ScaffoldColumn(false)] qui pose problème : avec cet attribut, le champ Id n'est pas représenté dans la page HTML sous forme d'<input> quelconque, donc sa valeur n'est pas renvoyée au serveur, et donc l'objet que tu récupères ne peut pas retrouver cette valeur.
    Le mieux (et au final le plus flexible à mon avis), c'est de créer un fichier RentPrice.cshtml dans le répertoire /Views/Shared/EditorTemplates (le répertoire est important) et de définir précisément les champs à afficher et comment. Genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @model RentPrice
    @Html.HiddenFor(model => model.Id)
        <div class="editor-label">
            @Html.LabelFor(model => model.Amount)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Amount)
            @Html.ValidationMessageFor(model => model.Amount)</div>
        <div class="editor-label">
            @Html.LabelFor(model => model.Type)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Type)
            @Html.ValidationMessageFor(model => model.Type)</div>
    La ligne @Html.HiddenFor(model => model.Id) te permet de définir ton champ Id en champ caché. Le reste permet un "joli" affichage de tes données

    Si en plus tu rajoutes des attributs Display à tes propriétés, alors la commande @Html.DisplayFor(...) se sert de la propriété Name de l'attribut pour un affichage encore plus joli !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    public class Rent
    {
        [Display(Name = "Id")]
        public Guid Id { get; set; }
        [Display(Name = "Référence")]
        public string Ref { get; private set; }
        [Display(Name = "Disponibilité")]
        public DateTime Availability { get; set; }
        [Display(Name = "Prix")]
        public virtual RentPrice Price { get; set; }
    }
    public class RentPrice
    {
        [Display(Name = "Id")]
        public Guid Id { get; set; }
        [Display(Name = "Montant")]
        public double Amount { get; set; }
        [Display(Name = "Type")]
        public RentPriceType Type { get; set; }
    }
    Enfin, joli... faut faire un peu de css pour que ce soit vraiment joli.

  5. #5
    Membre extrêmement actif

    Homme Profil pro
    Software Developer
    Inscrit en
    Mars 2008
    Messages
    1 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Software Developer

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 470
    Par défaut
    J'avais aussi essayé en retirant ScaffoldColumn et en utilisant un Hidden field mais je pensais qu'iil pourrais y avoir une meilleure solution (et que j'avais mal fait quelque chose comme je débute en MVC).

    Mais cela impose des restrictions comme pour: @Html.EditorFor(model => model.Price)
    A chaque ajout de nouvelle propriété dans mon modele il me faudra allez sur mes view et rajouter ce champs car il ne sera pas généré automatiquement.
    Cela impose donc d'avoir le model finalisé avant de commencer a générer les views.

    J'avais aussi pensé a utiliser un ViewModel, mais je pense que je serais confronté aux meme problemes et que mon code deviendrait tres vite une usine a gaz.

    Qu'en penses tu?

  6. #6
    Membre chevronné

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2011
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 244
    Par défaut
    Ce que j'ai oublié de dire, c'est qu'en utilisant la syntaxe de mon précédent post, tu peux garder la syntaxe @Html.EditorFor(model => model.Price).
    En effet, le moteur MVC identifie que l'objet Price est de type RentPrice et utilise le fichier /Views/Shared/EditorTemplates/RentPrice.cshtml.
    Si tu rajoutes des propriétés, tu n'auras donc qu'à modifier cet unique fichier.

    Pour l'affichage des données avec @Html.DisplayFor(model => model.Price), tu peux utiliser le fichier /Views/Shared/DisplayTemplates/RentPrice.cshtml

Discussions similaires

  1. Mettre en relation les contrôles DBLookUpComboBox et DBGrid
    Par Gendarmette dans le forum Bases de données
    Réponses: 7
    Dernier message: 19/01/2004, 13h16
  2. [EJB2.1 Entity] [CMR] Relation One to Many
    Par hamed dans le forum Java EE
    Réponses: 2
    Dernier message: 31/12/2003, 14h26
  3. Réponses: 2
    Dernier message: 26/09/2003, 15h54
  4. Problème avec mes tables de relation...
    Par mmike dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 02/06/2003, 15h16
  5. Réinitialisation
    Par kacedda dans le forum C
    Réponses: 3
    Dernier message: 13/12/2002, 04h56

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