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 :

LINQ TO ENTITIES - Requête impliquant une comparaison de collections


Sujet :

Entity Framework

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 14
    Points : 13
    Points
    13
    Par défaut LINQ TO ENTITIES - Requête impliquant une comparaison de collections
    Bonjour à tous,

    La qualité de vos contributions me poussent à revenir vers vous pour une difficulté que je rencontre dans le développement de mon application en .NET MVC 2. Je précise que je travaille avec Entity Framework.

    En effet, je développe un module de news qui actuellement affiche toutes les news entrées en base de données par ordre descendant de date de cette manière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
            public IQueryable<News> getAllNews()
            {
                var news = from n in _db.NewsSet
                           orderby n.LastChangedDate descending
                           select n;
                return news;  
            }
    Mon entité news contient une collection de l'entité Group. C'est à dire que chaque news est destinée à un ou plusieurs groupes.

    De la même manière l'entité user contient une collection de l'entité Group, et est inscrit à un ou plusieurs groupes.

    La difficulté serait donc de récupérer par la requête les news qui concernent les groupes auxquels l'utilisateur est inscrit.

    J'ai un contôleur qui fait appel à cette requête de cette manière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    allNews = _repository.getAllNews().ToList();
    Je peux récupérer les groupes de l'utilisateur ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    var user = _repository.getUserByUserName(HttpContext.User.Identity.Name,false);
    var userGroups = user.Groups;
    Le principe serait peut-être d'envoyer la liste des groupes de l'utilisateur en paramètre à la fonction "getAllNews", seulement je ne vois comment je pourrais faire la requête à partir de ces éléments.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Pourquoi ne pas utiliser la méthode Include qu'offre EF en chargeant les groupes lors de l'exécution de ta requête renvoyant les news ?

    Normalement la requête suivante devrait te permettre d'accéder aux groupes de chaque news non ?

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    // Je suppose que UserGroups est le nom de l'entité contenant les groupes
    public IQueryable<News> getAllNews()
            {
                var news = from n in _db.NewsSet.include("UserGroups")
                           orderby n.LastChangedDate descending
                           select n;
                return news;  
            }

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 14
    Points : 13
    Points
    13
    Par défaut
    J'ai chargé la liste des groupes des news comme tu me l'as indiqué,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
            public IQueryable<News> getAllNews()
            {
     
                var news = from n in _db.NewsSet.Include("Groups")
                           orderby n.LastChangedDate descending
                           select n;
     
                return news;
     
            }
    Ensuite dans mon contrôleur j'ai créé la méthode 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
     
            private List<News> visibleNewsByUser(List<News> allNews, ICollection<Group> userGroups)
            {
                List<News> news = new List<News>();
     
                allNews.ToList().ForEach((News n) =>
                {
                    foreach (var g in userGroups)
                    {
                        if (n.Groups.Contains(g) && !news.Contains(n) && n.IsVisible)
                            news.Add(n);
                    }
                });
     
                if (news.Count == 0)
                {
                    News defaut = _repository.getNewsById(46);
                    news.Add(defaut);
                }
                return news;
            }
    Cette solution correspond parfaitement à mon besoin, merci beaucoup pour ton aide.

  4. #4
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Points : 3 173
    Points
    3 173
    Par défaut
    Vous chargez toutes les news de la base de données pour seulement prendre celles concernant le current user!

    Quand vous aurez 20000 news en base dans 3-4 ans je ne donnes pas cher de l'application...

    Codez une fonction prenant en paramètre l'identifiant du user:
    public IQueryable<News> getAllNews(idUser)

    Et ne remontez avec votre requête LINQ que les news concernant le user... (via deux JOIN sur la tables des groupes et des user...)
    Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
    MCTS Database Development
    MCTS Database Administration

  5. #5
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Points : 3 173
    Points
    3 173
    Par défaut
    Vous pouvez également faire une fonction table ou une procédure stockée prenant en paramètre un userId,mappez là ensuite à votre EDMX, celà vous génère une méthodes dont vous pouvez typer le retour...
    Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
    MCTS Database Development
    MCTS Database Administration

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 14
    Points : 13
    Points
    13
    Par défaut
    Merci pour ce complément d'informations,

    je vais prendre en compte cette solution.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 21/03/2012, 13h34
  2. Linq To Entities : Problème sur une requête
    Par Invité dans le forum Linq
    Réponses: 5
    Dernier message: 14/09/2011, 14h28
  3. Réponses: 6
    Dernier message: 14/05/2009, 11h01
  4. Réponses: 0
    Dernier message: 29/04/2009, 16h35
  5. Réponses: 14
    Dernier message: 22/12/2008, 15h07

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