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 :

Suppression des orphelins


Sujet :

Entity Framework

  1. #1
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2010
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 95
    Points : 131
    Points
    131
    Par défaut Suppression des orphelins
    Bonjour,

    Je voudrais être capable de supprimer des orphelins dans une relation 1-*.

    Si j'en crois les différents tuto, cela à l'air d'être enfantin à réaliser. Tuto

    Dans ma base, j'ai une table Client et une table SuiviClient, laquelle à une clé étrangère non nullable Client_Id pointant sur la clé primaire de la table Client.

    Mon mappage ressemble à cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    modelBuilder.Entity<Client>()
                    .HasMany(c => c.ListeSuivi)
                    .WithRequired()
                    .HasForeignKey(c => c.Client_Id)
                    .WillCascadeOnDelete();
    modelBuilder.Entity<SuiviClient>()
                    .HasKey(s => new { s.Id, s.Client_Id })
                    .Property(s => s.Id)
                    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    Toutefois, quand je retire un suivi de la liste (et que le client associé devient null). La base de donnée me génère une exception me disant que la clé étrangère interdit les valeurs null.
    Soit, je suis d'accord, mais je m'attendais à ce que EF me supprime le suivi plutôt que d'essayer de le modifier comme expliqué dans le tuto plus haut.

    Ou est ce que je m'y prend mal ?

    Edit :

    Je reviens vers vous après avoir fait quelque test. J'ai essayé sur un petit projet de mettre en scène mon problème. Il se trouve que la gestion des orphelins est bien correctement géré à l'aide de .HasKey(s => new { s.Id, s.Client_Id }).

    Le soucis viens du fait qu'en réalité j'utilise de l'héritage avec un model Table Par Classe. J'ai donc SuiviClient qui hérite de la classe Suivi. Coté base de donnée, j'ai une table Suivi et une table SuiviClient.

    La table SuiviClient à une clé étrangère de son ID vers l'ID de la table Suivi.

    Dans ce cas la, je n'arrive plus à faire fonctionner la suppréssion des orphelins.

    Edit 2 :

    Un exemple concret :

    • Cas 1 : Sans héritage, le ContactClient est bien supprimé au moment du savechange après avoir supprimer la relation au client
      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
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
       
          public class Client
          {
              public Client()
              {
                  Contacts = new List<ContactClient>();
              }
       
              [Key, Column(Order = 1)]
              public int ID { get; set; }
       
              public virtual string Nom { get; set; }
       
       
              public virtual List<ContactClient> Contacts { get; set; }
          }
       
          [Table("ContactClients")]
          public class ContactClient 
          {
              [Key, Column(Order = 1)]
              public virtual int ID { get; set; }
       
              public virtual string Nom { get; set; }
       
              [Key, Column(Order = 2)]
              public int Client_ID { get; set; }
              [ForeignKey("Client_ID")]
              public virtual Client Client { get; set; }
          }
       
          public class Context : DbContext
          {
              public Context(string connectionString)
                  : base(connectionString)
              {
       
              }
       
              protected override void OnModelCreating(DbModelBuilder modelBuilder)
              {
                  modelBuilder.Entity<Client>()
                      .HasMany(c => c.Contacts)
                      .WithRequired()
                      .HasForeignKey(c => c.Client_ID)
                      .WillCascadeOnDelete();
                  modelBuilder.Entity<ContactClient>();
                  base.OnModelCreating(modelBuilder);
              }
          }
       
          static void Main(string[] args)
              {
                  try
                  {
                      Context context = new Context("TestAdhoc");
                      Client client = new Client() { Nom = "Hello" };
                      ContactClient contact = new ContactClient() { Nom = "World" };
                      client.Contacts.Add(contact);
                      context.Set<Client>().Add(client);
                      context.SaveChanges();
                      context.Dispose();
       
                      context = new Context("TestAdhoc");
                      client = context.Set<Client>().Single(c => c.Nom == "Hello");
                      client.Contacts.Remove(client.Contacts.Single(c => c.Nom == "World"));
                      context.SaveChanges();
                  }
                  catch(Exception e)
                  {
       
                  }
              }
    • Cas 2 : Avec héritage, le contactclient ne passe pas à l'état Deleted et le savechanges essaye d'insérer une valeur null dans la relation de clé étrangère vers le client ce qui génère une exception
      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
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
       
          public class Client
          {
              public Client()
              {
                  Contacts = new List<ContactClient>();
              }
       
              [Key, Column(Order = 1)]
              public int ID { get; set; }
       
              public virtual string Nom { get; set; }
       
       
              public virtual List<ContactClient> Contacts { get; set; }
          }
       
          public class Contact
          {
              [Key, Column(Order = 1)]
              public virtual int ID { get; set; }
       
              public virtual string Nom { get; set; }
          }
       
          [Table("ContactClients")]
          public class ContactClient : Contact
          {
              [Key, Column(Order = 2)]
              public int Client_ID { get; set; }
              [ForeignKey("Client_ID")]
              public virtual Client Client { get; set; }
          }
       
          public class Context : DbContext
          {
              public Context(string connectionString)
                  : base(connectionString)
              {
       
              }
       
              protected override void OnModelCreating(DbModelBuilder modelBuilder)
              {
                  modelBuilder.Entity<Client>()
                      .HasMany(c => c.Contacts)
                      .WithRequired()
                      .HasForeignKey(c => c.Client_ID)
                      .WillCascadeOnDelete();
                  modelBuilder.Entity<Contact>();
                  modelBuilder.Entity<ContactClient>();
                  base.OnModelCreating(modelBuilder);
              }
          }
       
          static void Main(string[] args)
              {
                  try
                  {
                      Context context = new Context("TestAdhoc");
                      Client client = new Client() { Nom = "Hello" };
                      ContactClient contact = new ContactClient() { Nom = "World" };
                      client.Contacts.Add(contact);
                      context.Set<Client>().Add(client);
                      context.SaveChanges();
                      context.Dispose();
       
                      context = new Context("TestAdhoc");
                      client = context.Set<Client>().Single(c => c.Nom == "Hello");
                      client.Contacts.Remove(client.Contacts.Single(c => c.Nom == "World"));
                      context.SaveChanges();
                  }
                  catch(Exception e)
                  {
       
                  }
              }


    Je tiens vraiment à supprimer mes orphelins de manière propre et éviter le workaround dans mes repositories ...

  2. #2
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2010
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 95
    Points : 131
    Points
    131
    Par défaut
    Je reviens pour reformuler ma question.

    Peut on faire des clés composées avec des classes hérités de classe mappé dans le modèle.

Discussions similaires

  1. Suppression des valeurs orphelines
    Par Patrice Henrio dans le forum Langage SQL
    Réponses: 1
    Dernier message: 06/10/2012, 00h55
  2. Réponses: 3
    Dernier message: 31/01/2005, 23h18
  3. [Lisp] Suppression des parenthèses dans une liste
    Par bourdaillet dans le forum Lisp
    Réponses: 3
    Dernier message: 19/12/2004, 21h02
  4. [Tomcat] Suppression des espaces
    Par bluefox_du_974 dans le forum Tomcat et TomEE
    Réponses: 5
    Dernier message: 16/12/2004, 21h54
  5. Réponses: 3
    Dernier message: 12/06/2002, 21h15

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