J'essaie de comprendre comment effectuer une jointure mixte dans LINQ avec un accès spécifique à 2 objets LINQ. Voici un exemple de la façon dont la requête TSQL réelle pourrait ressembler:Aide avec LINQ: Jointures jointes et spécification de valeurs par défaut
SELECT
*
FROM
[User] AS [a]
INNER JOIN
[GroupUser] AS [b]
ON
[a].[UserID] = [b].[UserID]
INNER JOIN
[Group] AS [c]
ON
[b].[GroupID] = [c].[GroupID]
LEFT JOIN
[GroupEntries] AS [d]
ON
[a].[GroupID] = [d].[GroupID]
WHERE [a].[UserID] = @UserID
A la fin, au fond ce que je voudrais est un objet dénombrable plein d'objets GroupEntry. Ce qui m'intéresse, ce sont les deux derniers tableaux/objets dans cette requête. Je vais afficher les groupes en tant qu'en-tête de groupe et toutes les entrées sous le titre de groupe. S'il n'y a pas d'entrées pour un groupe, je veux toujours voir ce groupe comme un en-tête sans aucune entrée. Voici ce que j'ai jusqu'à présent:
Donc, de ce que je voudrais faire une fonction:
public void DisplayEntriesByUser(int user_id)
{
MyDataContext db = new MyDataContext();
IEnumberable<GroupEntries> entries =
(
from user in db.Users
where user.UserID == user_id
join group_user in db.GroupUsers
on user.UserID = group_user.UserID
into a
from join1 in a
join group in db.Groups
on join1.GroupID equals group.GroupID
into b
from join2 in b
join entry in db.Entries.DefaultIfEmpty()
on join2.GroupID equals entry.GroupID
select entry
);
Group last_group_id = 0;
foreach(GroupEntry entry in entries)
{
if (last_group_id == 0 || entry.GroupID != last_group_id)
{
last_group_id = entry.GroupID;
System.Console.WriteLine("---{0}---", entry.Group.GroupName.ToString().ToUpper());
}
if (entry.EntryID)
{
System.Console.WriteLine(" {0}: {1}", entry.Title, entry.Text);
}
}
}
L'exemple ci-dessus ne fonctionne pas tout à fait comme prévu. Il y a 2 problèmes que je ne l'ai pas été en mesure de résoudre:
Il me semble encore être obtenir un INNER JOIN au lieu d'un LEFT JOIN sur la dernière jointure. Je n'obtiens aucun résultat vide, donc les groupes sans entrées n'apparaissent pas.
J'ai besoin de trouver un moyen pour que je puisse remplir les valeurs par défaut pour les ensembles d'entrées vierges. C'est-à-dire, s'il y a un groupe sans une entrée, je voudrais avoir une entrée principalement vide, sauf que je voudrais que l'EntryID soit nul ou 0, le GroupID soit celui du groupe vide qu'il représente , et j'ai besoin d'un handle sur l'objet entry.Group (c'est-à-dire c'est parent, objet Group vide).
Toute aide à ce sujet serait grandement appréciée.
Remarque: Les noms de tables et la représentation du monde réel ont été dérivés uniquement pour cet exemple, mais leurs relations simplifient ce que j'essaie de faire.
Merci beaucoup Dan. C'est une requête beaucoup plus simple. Je tombe dans des ennuis plus tard dans le code derrière. Ma fonction actuelle attend un type d'objet IEnumberable à travers lequel il peut itérer. À l'heure actuelle, dans ma boucle foreach, après la requête, j'obtiens l'erreur «Default de surcharge non utilisée pour l'opérateur de requête 'DefaultEmpty'». Sur une note relative à la curiosité, si vous utilisez le mot clé "into" dans linq, crée-t-il nécessairement une sous-requête à la couche db inférieure? –
Corey, est-ce une requête LinqToSql? – devuxer
Yessir. La base de données sous-jacente est un serveur MSSQL 2005. –