Entity Framework Join 3 Tables

133

J'essaye de joindre trois tables mais je ne comprends pas la méthode ...

J'ai terminé joindre 2 tables

        var entryPoint = dbContext.tbl_EntryPoint
            .Join(dbContext.tbl_Entry,
                c => c.EID,
                cm => cm.EID,
                (c, cm) => new
                {
                    UID = cm.OwnerUID,
                    TID = cm.TID,
                    EID = c.EID,
                }).
            Where(a => a.UID == user.UID).Take(10);

les tables

Je voudrais inclure la table tbl_Title avec TID PK et obtenir le champ Titre .

Merci beaucoup

Erçin Dedeoğlu
la source
Consultez cet article connexe. Il n'utilise pas la notation de la méthode, mais vous devriez pouvoir obtenir l'essentiel ... stackoverflow.com/questions/11204367/…
xspydr
Veuillez montrer une image avec des propriétés de navigation étendues. Les propriétés de navigation sont des jointures prêtes à l'emploi.
Gert Arnold

Réponses:

202

Je pense que ce sera plus facile en utilisant une requête basée sur la syntaxe:

var entryPoint = (from ep in dbContext.tbl_EntryPoint
                 join e in dbContext.tbl_Entry on ep.EID equals e.EID
                 join t in dbContext.tbl_Title on e.TID equals t.TID
                 where e.OwnerID == user.UID
                 select new {
                     UID = e.OwnerID,
                     TID = e.TID,
                     Title = t.Title,
                     EID = e.EID
                 }).Take(10);

Et vous devriez probablement ajouter une orderbyclause pour vous assurer que Top(10)les dix premiers éléments sont corrects.

MarcinJuraszek
la source
3
Merci beaucoup pour la méthode; fonctionne clairement mais j'aimerais voir la réponse comme je l'ai demandé, merci beaucoup encore.
Erçin Dedeoğlu
@MarcinJuraszek: si j'ai besoin d'un ViewModel pour fonctionner, est-il nécessaire que je rejoigne les tables?
Vini
Cela ne fonctionne pas même sans asynchrone. J'ai le scénario exact mais la requête lève une exception [the_list_of_all_return_variables] 'ne peut pas être sérialisée. @marcinJuraszek - Pourriez-vous jeter un oeil à stackoverflow.com/questions/42453123/…
sandiejat
1
PARFAIT! tu m'as fait gagner beaucoup de temps :)
MohammadHossein R
81

Ceci n'est pas testé, mais je pense que la syntaxe devrait fonctionner pour une requête lambda. Au fur et à mesure que vous joignez plus de tables avec cette syntaxe, vous devez explorer les nouveaux objets pour atteindre les valeurs que vous souhaitez manipuler.

var fullEntries = dbContext.tbl_EntryPoint
    .Join(
        dbContext.tbl_Entry,
        entryPoint => entryPoint.EID,
        entry => entry.EID,
        (entryPoint, entry) => new { entryPoint, entry }
    )
    .Join(
        dbContext.tbl_Title,
        combinedEntry => combinedEntry.entry.TID,
        title => title.TID,
        (combinedEntry, title) => new 
        {
            UID = combinedEntry.entry.OwnerUID,
            TID = combinedEntry.entry.TID,
            EID = combinedEntry.entryPoint.EID,
            Title = title.Title
        }
    )
    .Where(fullEntry => fullEntry.UID == user.UID)
    .Take(10);
Pynt
la source
17
C'est hideux. Si jamais je trouvais une telle requête dans le code de production, je la refactoriserais immédiatement. +1 pour avoir répondu à la question posée, cependant!
Dan Bechard
8
@Dan Par curiosité, est-ce juste la non-pensée du tout des conventions de nommage avec les c, cm et ccm, ou simplement la syntaxe requise pour effectuer les jointures en utilisant linq et lambda qui est hideuse? Si le premier, et que vous souhaitez modifier le message pour avoir une meilleure mise en page, vous l'avez certainement. Je suis encore nouveau dans le cadre d'entité et je suis toujours plongé dans les meilleures pratiques, donc si vous avez des suggestions pour rendre cette réponse plus éloquente pour les futurs utilisateurs, j'apprécierais l'aide.
Pynt
4
Je n'avais pas beaucoup réfléchi à la raison exacte lorsque j'ai commenté, mais les conventions de dénomination nuisent certainement à la lisibilité (évidemment copié à partir de OP). De plus, les virgules au début de la ligne nuisent beaucoup à la lisibilité (subjective, pour moi), et les espaces / indentations pourraient être légèrement améliorés. J'ai soumis une modification avec toutes ces améliorations (IMHO) depuis que vous l'avez demandé.
Dan Bechard
2
Le formatage du code est souvent biaisé, mais il y a des choses générales que la plupart des gens reconnaissent mieux. En ce qui concerne les conventions de dénomination, j'avais l'habitude d'appeler les choses des noms très courts, mais je peux taper beaucoup assez rapidement maintenant (sans même considérer des choses comme Intellisense) que les quelques caractères enregistrés ne valent pas le détriment en lisibilité par rapport à nommer les choses de manière verbeuse, par exemple "EntryID" contre "EID", "combinéEntry" contre "cm", etc. Finalement, quelqu'un d'autre va lire mon code, et je préférerais qu'il ne me haine pas en fonction linéaire du nombre de lignes de mon code qu'ils ont dû lire / maintenir.
Dan Bechard
5
Je ne comprends tout simplement pas les arguments contre les virgules de départ. Je suis fermement convaincu, car il est très facile de commenter des clauses / arguments individuels. Et ça a l'air plus joli :-)
Auspex