Синтаксис метода (= синтаксис с лямбда-выражениями) обладает большей функциональностью, чем синтаксис запроса.Поэтому я предпочитаю использовать синтаксис метода выше синтаксиса запроса.
Однако есть одно исключение: при объединении трех или более таблиц синтаксис метода выглядит отвратительно, как Себу показал в своем ответе.Is также показан в в этом ответе, где сравниваются два метода объединения трех таблиц
Внутренне выражение в IQueryable
одинаково, независимо от того, используете ли вы синтаксис метода илисинтаксис запроса, поэтому результирующий оператор SQL не будет сильно отличаться.
Поэтому я бы посоветовал: использовать синтаксис метода всякий раз, когда это возможно, но для удобства чтения, меньше ошибок, для удобства сопровождения: объедините три таблицы, используя синтаксис запроса.
Если вам приходится выполнять объединение трех таблиц довольно часто, рассмотрите возможность создания функции расширения, которая скрывает способ выполнения объединения:
См .: Демистифицированные функции расширения
Следующая функция принимает три входные последовательности: IQueryable, IQueryable и IQueryable.
Она объединяет первые две последовательности на ключах, извлеченных с использованием T1Join1Selector и T2Join1Selector,
Если объединяет последние две последовательности на ключах, вынутых с использованием T2Join2Selectorи T3Join2Selector
от каждого соответствующегоT1 / T2 / T3 создает один результат в соответствии с resultSelector
public static IQueryable<TResult> Join<T1, T2, T3,
TKeyJoin1, TKeyJoin2, TResult>(
this IQueryable<T1> table1,
IQueryable<T2> table2,
IQueryable<T3> table3,
Expression<Func<T1, TKeyJoin1>> table1Join1KeySelector,
Expression<Func<T2, TKeyJoin1>> table2Join1KeySelector,
Expression<Func<T2, TKeyJoin2>> table2Join2KeySelector,
Expression<Func<T3, TKeyJoin2>> table3Join2KeySelector,
Expression<Func<T1, T2, T3, Tresult>> resultSelector)
{
return Tabl1.Join(table2, // join table1 and table2
t1 => table1Join1KeySelector(t1), // select the key from table1 for the first join
t2 => table2Join1KeySelector(t2), // select the key from table2 for the first join
(t1, t2) => new // remember the matching records as T1 and T2
{
T1 = t1,
T2 = t2,
})
// use this as input for the second join:
.Join(table3,
// use the T2 in the result of the first join as key for the second join
joinedT1andT2 => table2Join2KeySelector(joinedT1andT2.T2),
t3 => table3Join2KeySelector(t3), // select the key from table3 for the 2nd join
// and use the result of the first and second join to create a linq-result:
(joinedT1andT2, t3) => resultSelector(joinedT1andT2.T1, joinedT1andT2.T2, T3);
}
Альтернативно объедините три таблицы, используя синтаксис запроса:
public static IQueryable<TResult> Join<T1, T2, T3,
TKeyJoin1, TKeyJoin2, TResult>(
this IQueryable<T1> table1,
IQueryable<T2> table2,
IQueryable<T3> table3,
Expression<Func<T1, TKeyJoin1>> table1Join1KeySelector,
Expression<Func<T2, TKeyJoin1>> table2Join1KeySelector,
Expression<Func<T2, TKeyJoin2>> table2Join2KeySelector,
Expression<Func<T3, TKeyJoin2>> table3Join2KeySelector,
Expression<Func<T1, T2, T3, Tresult>> resultSelector)
{
return select resultSelector(table1, table2, table3)
from table1
join table2 on table1Join1KeySelector(table1) == table2Join1KeySelector(table2)
join table3 on table2Join2KeySelector(table2) == table3Join2KeySelector(table3)
}
Использование аналогично соединению двух таблиц с использованиемСинтаксис метода:
var result = a.Join(b, c, // join your tables a, b, c
t1 => t1.PayoutId, // first join on a.PayoutID = b.PayoutID
t2 => t2.PayoutId,
t2 => t2.UserId, // second join on b.UserID = c.UserID
t3 => t3.UserId,
(t1, t2, t3) => new // from the matching records create one new object
{
PayoutId = t1.PayoutId,
PayoutName = t2.PayoutName,
...
});
Я видел, что ваше второе соединение было на a и c, в то время как мое второе соединение было на b и c.Я уверен, что вы знаете, как переписать код в соответствии с вашими потребностями
Поскольку результатом этой функции является IQueryable, функция будет изменять только выражение.Запрос еще не выполнен.Поэтому вы можете безопасно смешивать это с другими функциями IQueryable:
var resultQuery = a.Where(t1 => t1.Name = ...)
.Join( /* 3-table join as described above */ )
.GroupBy(joinResult => ...)
.Take(4);
Запрос по-прежнему не выполняется, пока вы не сделаете что-то, что не возвращает IQueryable
, например ToList
/ FirstOrDefault
/ Any
/ ...