Il existe de nombreux articles concernant LINQ et les jointures multiples. Je n'ai cependant pas trouvé de solution au joint que je voudrais faire.
L'équivalent SQL serait quelque chose comme ceci:
SELECT * FROM table1 a
LEFT JOIN table2 b ON a.col1 = b.key1 AND
a.col2 = b.key2 AND
b.from_date <= now() AND
b.deleted = 0;
Voici l'une des nombreuses requêtes linq que j'ai tentées
var query = (from x in context.table1
join y in context.table2 on new {x.col1, x.col2} equals {b.key1, b.key2}
into result
from result......
Comment puis-je ajouter les conditions supplémentaires de la date et du drapeau supprimé? Si j'utilise des conditions .Where, cela est traité comme une jointure interne et non comme une jointure gauche.
Une autre façon pourrait être comme
var query = (from x in context.table1
join y in context.table2 on
new {
Key1 = x.col1,
Key2 = x.col2,
Key3 = true,
Key4 = true
}
equals
new {
Key1 = y.key1,
Key2 = y.key2,
Key3 = y.from_date< DateTime.Now,
Key4 = !y.deleted
}
into result
from r in result.DefaultIfEmpty()
select new {x.Something, r.Something}
LINQ prend en charge la syntaxe de jointure et l'ancienne syntaxe ANSI-82 WHERE. En utilisant ce dernier, vous pouvez faire ce que vous recherchez sur une jointure interne avec
var nowTime = DateTime.Now;
var query = from a in context.table1
from b in context.table2
where a.col1 == b.key1
&& a.col2 == b.key2
&& b.from_date < nowTime
&& b.deleted == false
select ???;
Pour une jointure externe, je préfère une syntaxe utilisant un hybride d'où et sélectionnez plusieurs. (Sachez que l'ordre dans la requête LINQ n'a pas besoin d'imiter ce que vous feriez dans SQL et l'ordre est plus flexible.)
var nowTime = DateTime.Now;
var query = from b in context.table2
from a1 in a.Where(a2 =>
b.key1 = a.col &&
b.key2 = a.col2 &&
b.from_date < nowTime &&
b.deleted == false).DefaultIfEmpty()
select ???;
J'ai eu un problème avec le nommage des propriétés dans un objet anonyme:
var subscriptions = context.EmailSubscription.Join(context.EmailQueue,
es => new { es.Id, 9 },
eq => new { eq.EmailSubscriptionId, eq.EmailTemplateId },
(es, eq) => new { es.Id, eq.Id }
).ToList();
Le compilateur n'était pas content, donc la réponse ci-dessus m'aide à comprendre ce qui n'allait pas et voici ma solution de travail. Il m'a fallu un certain temps pour trouver une erreur stupide :):
var subscriptions = context.EmailSubscription.Join(context.EmailQueue,
es => new { EmailSubscriptionId = es.Id, EmailTemplateId = 9 },
eq => new { eq.EmailSubscriptionId, eq.EmailTemplateId },
(es, eq) => new { es.Id, eq.Id }
).ToList();
Ne pourriez-vous pas simplement filtrer le 1er jeu de résultats avec une deuxième requête?
var query = (from x in context.table1
join y in context.table2 on new {x.col1, x.col2} equals {b.key1, b.key2}
into result
query = from x in query
where ...
Cela fonctionnerait-il?
En plus de la réponse de @Muhammad Adeel Zahid, vous pouvez également utiliser plusieurs conditions telles que:
new
{
Key1 = ppl.PeopleId,
Key2 = true,
Key3 = true
}
equals
new
{
Key1 = y.PeopleId,
Key2 = !y.IsDeleted,
Key3 = (y.RelationshipType == 2 || y.RelationshipType == 4)
}