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 :

Entity Framework - référence circulaire


Sujet :

Entity Framework

  1. #1
    Débutant  
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    1 225
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 225
    Points : 132
    Points
    132
    Par défaut Entity Framework - référence circulaire
    Bonjour,

    J'utilise Entity Framework pour accéder à ma base de données. J'ai donc générer mes classes depuis m'a base de données.
    Par exemple, voici la classe Etudiant et Classe:
    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
     
    //------------------------------------------------------------------------------
    // <auto-generated>
    //    Ce code a été généré à partir d'un modèle.
    //
    //    Des modifications manuelles apportées à ce fichier peuvent conduire à un comportement inattendu de votre application.
    //    Les modifications manuelles apportées à ce fichier sont remplacées si le code est régénéré.
    // </auto-generated>
    //------------------------------------------------------------------------------
     
    namespace GestionNoteWeb.Models
    {
        using System;
        using System.Collections.Generic;
     
        public partial class Etudiant
        {
            public Etudiant()
            {
                this.Note = new HashSet<Note>();
            }
     
            public int idEtudiant { get; set; }
            public string nomEtudiant { get; set; }
            public string prenomEtudiant { get; set; }
            public string emailEtudiant { get; set; }
            public string telephoneEtudiant { get; set; }
            public Nullable<int> classe { get; set; }
     
            public virtual Classe Classe1 { get; set; }
            public virtual ICollection<Note> Note { get; set; }
        }
    }
    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
    //------------------------------------------------------------------------------
    // <auto-generated>
    //    Ce code a été généré à partir d'un modèle.
    //
    //    Des modifications manuelles apportées à ce fichier peuvent conduire à un comportement inattendu de votre application.
    //    Les modifications manuelles apportées à ce fichier sont remplacées si le code est régénéré.
    // </auto-generated>
    //------------------------------------------------------------------------------
     
    namespace GestionNoteWeb.Models
    {
        using System;
        using System.Collections.Generic;
     
        public partial class Classe
        {
            public Classe()
            {
                this.ClasseMatiere = new HashSet<ClasseMatiere>();
                this.Devoir = new HashSet<Devoir>();
                this.Etudiant = new HashSet<Etudiant>();
            }
     
            public int idClasse { get; set; }
            public string nomClasse { get; set; }
            public Nullable<int> professeurPrincipal { get; set; }
     
            public virtual ICollection<ClasseMatiere> ClasseMatiere { get; set; }
            public virtual ICollection<Devoir> Devoir { get; set; }
            public virtual ICollection<Etudiant> Etudiant { get; set; }
            public virtual Professeur Professeur { get; set; }
        }
    }
    Par exemple, quand je cherche la liste des Etudiants, sa me met une erreur du type référence circulaire. En effet, un Etudiant est dans une classe, une Classe possède plusieurs Etudiant. Du coup, dans la Classe Etudiant, j'ai int classe, qui correspond à l'id dans la bd, et Classe Classe1 qui fait la liaison avec la table classe. J'ai plus ou moins la même chose dans la classe Classe.

    Ma question est : est-normal d'avoir dans la classe Etudiant, les 2 attribut classe et Classe1, dans la classe Classe avoir la collection Etudiant ? Si c'est pas normal, comment améliorer cela ?
    Comment éviter les références circulaire?

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 025
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2 025
    Points : 5 462
    Points
    5 462
    Par défaut
    Je vois pas de reference circulaire.

    Les liens virtuels c'est un "bonus" que t'offre Entity Framework, en te donnant un lien direct vers la ou les instances en relation.

    Un élève a bien une classe avec un ID, qu'EF te permet de récupérer directement via Classe1. (Attention ici tu peux vite avoir des problèmes de lazy/ egger loading en fonction de la configuration et de ce que tu cherches à avoir).

    De même EF à compris que comme chaque élève possède 0 ou une classe, une classe à forcément 0 ou n élèves associés, il te propose donc depuis Classe d'aller chercher pour toi la liste des élève associés.

    Ce n'est pas obligatoire, ni d'avoir ces liens physiques dans tes classes ( navigation/relation d'EF : https://msdn.microsoft.com/en-us/lib...=vs.113).aspx) , ni de les charger automatiquement(cf egger/lazy loading : http://www.dotnettricks.com/learn/en...-eager-loading).

  3. #3
    Débutant  
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    1 225
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 225
    Points : 132
    Points
    132
    Par défaut
    Quand je charge ma liste d'étudiant, il me lance une exception.
    Référence circulaire détectée lors de la sérialisation d'un objet de type 'System.Data.Entity.DynamicProxies.Classe_ADD4019E30297A823FBBB9E0866C14B1C7AAB8CB9426AE7CD7E4A630E9021047'.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public JsonResult GetAllEtudiants()
    {
        var etudiantsListe = contextObj.Etudiant.ToList();
     
        return Json(etudiantsListe, JsonRequestBehavior.AllowGet);
    }

  4. #4
    Membre habitué
    Homme Profil pro
    Ingénieur .Net
    Inscrit en
    Décembre 2014
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur .Net
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2014
    Messages : 71
    Points : 147
    Points
    147
    Par défaut
    Comme la dit @micka132 :

    il te propose donc depuis Classe d'aller chercher pour toi la liste des élèves associés.
    Il va donc te récupérer automatiquement les valeurs des propriétés de navigation.

    Dans ton cas, lorsque tu souhaite le sérialiser en JSON, ce dernier rentre bien dans une boucle infini à cause d'une référence circulaire (Etudiant -> Classe -> Etudiant -> etc...)

    Pour cela tu as deux choix.

    Choix 1 :


    Changer la façon dont EF récupère les données.
    Par défaut le LazyLoading est activé, tu peux le désactiver et faire les inclusions à la main selon tes besoins.
    Bien entendu cela ne résoudra pas tous les cas.

    CF : lien de @micka132 sur le lazyloading

    Choix 2 :

    C'est la meilleure chose et une bonne pratique à prendre, c'est de ne pas renvoyer directement l'objet venant de la base mais de le mapper dans un ViewModel pour ne choisir que les informations dont tu as besoins

    Pour conclure, il est généralement de bonne pratique de ne pas utiliser le Lazy Loading pour éviter le chargement inutile de données et donc d'utiliser des ressources et de l'I/O inutilement et de combiner cela avec des ViewModels pour séparer un minimum les données d'affichages, des données venant de ta base.

  5. #5
    Débutant  
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    1 225
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 225
    Points : 132
    Points
    132
    Par défaut
    Le ViewModel correspond à un DTO ? Car je ne vois pas à quoi cela correspond sinon

  6. #6
    Membre habitué
    Homme Profil pro
    Ingénieur .Net
    Inscrit en
    Décembre 2014
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur .Net
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2014
    Messages : 71
    Points : 147
    Points
    147
    Par défaut
    Citation Envoyé par totot Voir le message
    Le ViewModel correspond à un DTO ? Car je ne vois pas à quoi cela correspond sinon
    Alors le view model ne peut pas correspondre à un DTO.

    DTO => Data Transfet Object

    C'est un pattern

    Par contre il peux être identique à un DAO (Data Access Object) qui lui est juste un objet avec Getter et Setter pour accéder plus facilement aux données.

    Le ViewModel peux être une copie conforme d'un DAO, mais en général on y ajoute des propriétés ou en en modifie d'autres pour facilité l'affichage.

    Par exemple dans ta class Etudiant tu as

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
            public string nomEtudiant { get; set; }
            public string prenomEtudiant { get; set; }

    Un ViewModelEtudiant pourrait avoir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public string NomCompletEtudiant { get; set; }
    Cela évitera coté Front de faire la concaténation du nom et du prénom

  7. #7
    Débutant  
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    1 225
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 225
    Points : 132
    Points
    132
    Par défaut
    Dans mon ViewModelEtudiant, je peux avoir tous les informations telles qu'elles que j'ai dans la classe étudiant par exemple ?

  8. #8
    Membre habitué
    Homme Profil pro
    Ingénieur .Net
    Inscrit en
    Décembre 2014
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur .Net
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2014
    Messages : 71
    Points : 147
    Points
    147
    Par défaut
    Citation Envoyé par totot Voir le message
    Dans mon ViewModelEtudiant, je peux avoir tous les informations telles qu'elles que j'ai dans la classe étudiant par exemple ?
    Oui, tu peux avoir toutes les informations que tu veux et surtout dont tu as besoin

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

Discussions similaires

  1. C# Entity framework référence du schema
    Par Kcintim dans le forum Entity Framework
    Réponses: 1
    Dernier message: 23/01/2017, 09h22
  2. [SQL 2K5] Pb : ON DELETE CASCADE : référence circulaire
    Par n00bi dans le forum MS SQL Server
    Réponses: 10
    Dernier message: 29/05/2006, 08h48
  3. Référence circulaire
    Par Mvu dans le forum ASP
    Réponses: 3
    Dernier message: 27/04/2006, 14h38
  4. [EXCEL] : référence circulaire à cause d'une macro
    Par repié dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 11/01/2006, 10h41
  5. [DEB] DBdesigner 4 et référence circulaire
    Par Ranbaz dans le forum DBDesigner
    Réponses: 1
    Dernier message: 13/07/2005, 17h32

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