I'm not really familiar with query syntax for LINQ, hence I'll show how to do it using Method syntax.
You want to join several tables, and after some joins, you want to join with table P. But you don't want to join all previous join results with table P, you only want to use those previous join results that that have an x.n equal to 3 or 4.
If you will throw away all previous join results with x.N value neither 3, nor 4, then it's no use to put them in the previous join result anyway:
var requiredNvalues = new int[] {3, 4};
var result = X
.Where(x => requiredNvalues.Contains(x.N) // keep only the required x elements
// Join the remaining elements of X with Y:
.Join(Y,
x => x.A, // from every x in X take the A
y => y.A, // from every y in Y take y.A
// ResultSelector: when they match make one new object containing matching X and Y
(x, y) => new {X=x, Y=y})
// join with third table:
.Join(Z,
previousJoinResult => previousJoinResult.X.Id,
// from every item in previous join result take X.Id
z => z.xId, // from every z from Zcollection take Xid,
// ResultSelector: when they match make one new object containing matching X Y Z
(previousJoinResult, z) => new {X = previousJoinResult.X, Y = previousJoinResult.Y, Z = z}
... etc, other joins
Coninue joining in a similar way until you want to join P:
.Join(P,
previousJoinResult => previousJoinResult.X.b,
// from every X from the previous join result take b
p => p.b // from every p take b
// resultSelector: select X Y Z ... P
(previousJoinResult, p) => new
{
X = previousJoinResult.X,
Y = previousJoinResult.Y,
Z = previousJoinResult.Z,
...
P = p;
});
Simple comme bonjour!