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 :

Mode TPT au lieu de TPC en Code First


Sujet :

Entity Framework

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2006
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 149
    Points : 90
    Points
    90
    Par défaut Mode TPT au lieu de TPC en Code First
    salut à tous.

    voila, d'erreur en erreur j'ai réussi à identifier de manière plus ou moins précise mon problème.

    j'ai deux classes "cadre" et "Technicien" qui héritent d'une classe abstraite "Personne".

    j'ai aussi mon dbcontext qui contient l'entité "Personne" (je sais pas trop si c'est comme ca qu'on dit, mais j'espere, vous m'aurez compris)

    donc souhaitant générer ma database par le "mode" Table Per Class à l'aide de l'API Fluent, je surcharge la méthode OnModeICreating de la manière suivante :

    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
     
     protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
     
                modelBuilder.Entity<Cadre>().Map(m =>
                    {
                        m.MapInheritedProperties();
                        m.ToTable("Cadre");
                    });
     
                modelBuilder.Entity<Cadre>().Property(p => p.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
     
                modelBuilder.Entity<Technicien>().Map(m =>
                {
                    m.MapInheritedProperties();
                    m.ToTable("Technicien");
                });
     
                modelBuilder.Entity<Technicien>().Property(p => p.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
     
     
            }
    sauf que je me retrouve avec l'erreur suivante :

    Les modifications apportées à la base de données ont été validées, mais une erreur s'est produite lors de la mise à jour du contexte de l'objet. ObjectContext est peut-être dans un état incohérent. Message d'exception interne : AcceptChanges ne peut pas continuer, car les valeurs de clés de l'objet sont en conflit avec un autre objet dans ObjectStateManager. Assurez-vous que les valeurs de clés sont uniques avant d'appeler AcceptChanges.
    en fouillant un peu j'ai compris qu'il s'agissait de ma clé primaire qui s'incrémentait pas, et c'est normal puisque je le gère pas dans le code et j'attends de mon SGBD qu'il le fasse de lui meme. Sauf que dans ma base, je me retrouve avec mes tables "Cadre" et "Technicien" avec le bon champ Id en PK, mais non "auto-incrémenté", et en plus j'ai une table "Personne", qui elle en revanche possède un champ Id en PK et auto-incrémenté (le mode TPT quoi).

    j'ai suivi pas mal de tutos, dont celui ci entre autre :

    http://weblogs.asp.net/manavi/archiv...uidelines.aspx

    je reste à l'écoute de toute suggestion.

    merci d'avance.

  2. #2
    Membre éprouvé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Septembre 2005
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 462
    Points : 1 056
    Points
    1 056
    Par défaut
    --> " m.MapInheritedProperties();" est utilisé pour faire du TPC.

    Tu trouvera deux exemple ci dessous.
    Mes commentaires au début explique le fonctionnement des différents mise en oeuvre de TPT et TPC !

  3. #3
    Membre éprouvé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Septembre 2005
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 462
    Points : 1 056
    Points
    1 056
    Par défaut
    Voici un code d'exemple TPT :

    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
    /// <summary>
        /// Table per Type (TPT)
        /// Une table par type
        /// Trois tables : 
        ///     - Une table pour Vehicule(colonne de vehicule)
        ///     - Une table pour Voiture(colonne de voiture)
        ///     - Une table pour Moto(colonne de moto)
        /// On peut le faire de deux facon :
        ///     - Grace a FLUENT : modelBuilder.Entity<Voiture>().ToTable("Voiture");
        ///     - Grace au attribut : [Table("Voiture")]
        /// </summary>
        public abstract class Vehicule
        {
            public int VoitureId { get; set; }
            public string Nom { get; set; }
            public int NbRoues { get; protected set; }
        }
        //[Table("Voiture")]
        public class Voiture : Vehicule
        {
            public int NbPortes { get; set; }
            public Voiture()
            {
                NbRoues = 4;
            }
        }
        //[Table("Moto")]
        public class Moto : Vehicule
        {
            public Moto()
            {
                NbRoues = 2;
            }
        }
    Context :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                //Vehicule Technique TPT :
                modelBuilder.Entity<Vehicule>().HasKey(p => p.VoitureId);
                modelBuilder.Entity<Vehicule>().Property(p => p.Nom).HasMaxLength(50).IsRequired();
                modelBuilder.Entity<Voiture>().ToTable("Voiture");
                modelBuilder.Entity<Moto>().ToTable("Moto");
     
            }

  4. #4
    Membre éprouvé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Septembre 2005
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 462
    Points : 1 056
    Points
    1 056
    Par défaut
    Voici un exemple de TPC :

    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
    /// <summary>
        /// Table per Concrete class (TPC)
        /// Un table par type concret.
        /// Deux tables :
        ///     - Une table Chien(colonne d'animal et de chien)
        ///     - Une table Chat(colonne d'animal et de chat)
        /// Par contre cette méthode génére un problème d'id
        /// avec les tables splitté, Les solution sont :
        ///     - Enlever l'identity
        ///     - Changer de mode d'id (GUID)
        /// Mise en oeuvre :
        ///     - Par attribut : [DatabaseGenerated(DatabaseGeneratedOption.None)]
        ///     - Par FLUENT : modelBuilder.Entity<Animal>()
        ///             .Property(p => p.AnimalId)
        ///             .HasDatabaseGenerationOption(DatabaseGenerationOption.None);
        /// Cette méthode ne peut mise en oeuvre que par FLUENT :
        ///     modelBuilder.Entity<Chat>().Map(m => {
        ///        m.MapInheritedProperties();
        ///        m.ToTable("Chat");
        ///    }); 
        /// </summary>
        public abstract class Animal
        {
            [DatabaseGenerated(DatabaseGeneratedOption.None)]
            public int AnimalId { get; set; }
            [Required, MaxLength(50)]
            public string Nom { get; set; }
        }
     
        public class Chat : Animal
        {
            public int NbMoustache { get; set; }
        }
     
        public class Chien : Animal
        {
            public int? NbCroc { get; set; }
        }
    Context :
    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
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
     
                //Animal Technique TPC
                modelBuilder.Entity<Chat>().Map(m =>
                {
                    m.MapInheritedProperties();
                    m.ToTable("Chat");
                });
                modelBuilder.Entity<Chien>().Map(m =>
                {
                    m.MapInheritedProperties();
                    m.ToTable("Chien");
                });
            }

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Février 2006
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 149
    Points : 90
    Points
    90
    Par défaut
    kat y a rien a dire t'es un killer !!!

    en gros pour faire du TPC (c'est ce qui m'intéresse ici) tu spécifies explicitement que l'ID de Animal ne doit pas etre une "IDENTITE" via le dataAttribute. mais y a-t-il moyen de faire ca par l'API Fluent ?

    je pense que mon probleme est la.

    merci à toi

  6. #6
    Membre éprouvé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Septembre 2005
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 462
    Points : 1 056
    Points
    1 056
    Par défaut
    Oui oui tout à fait c'était dans mon exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    modelBuilder.Entity<Animal>()
                     .Property(p => p.AnimalId)
                     .HasDatabaseGenerationOption(DatabaseGenerationOption.None);

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Février 2006
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 149
    Points : 90
    Points
    90
    Par défaut
    c'est intéressant ca, parce que c'est exactement ce que j'ai mis en place et voici le retour (en erreur) :

    Conflicting configuration settings were specified for property 'ID' on type 'CFDTO.Personne':
    DatabaseGeneratedOption = None conflicts with DatabaseGeneratedOption = Identity

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Février 2006
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 149
    Points : 90
    Points
    90
    Par défaut
    bon, j'ai contourné mon problème (a vrai dire je suis passé à autre chose). Je mets en place le TPT, qui répond bien au besoin, et qui a l'air d'etre meilleur que le TPC selon certaines documentations, celle ci en l'occurrence :

    http://blogs.msdn.com/b/alexj/archiv...-strategy.aspx

    si quelqu'un veut enrichir, welcome ;-)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 08/07/2015, 15h05
  2. [AC-2007] Form ouvre en mode formulaire au lieu de feuille de données
    Par Piou2fois dans le forum IHM
    Réponses: 4
    Dernier message: 05/04/2013, 11h38
  3. Réponses: 10
    Dernier message: 17/05/2011, 22h45
  4. [EF Code First] Relations entre tables
    Par john85 dans le forum ASP.NET MVC
    Réponses: 5
    Dernier message: 06/05/2011, 19h12
  5. exécuter du html au lieu d'afficher le code
    Par laurentSc dans le forum Langage
    Réponses: 12
    Dernier message: 18/11/2009, 12h35

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