конвертировать сценарий sql join в лямбду или linq - PullRequest
0 голосов
/ 25 июня 2018

как я могу преобразовать этот скрипт в лямбда или linq?

 select a.PayoutID,b.PayoutName 
   from [dbo].[PayoutsOfUser] a 
  inner join [dbo].[Payout] b on a.PayoutID = b.PayoutID
  inner join [dbo].[Users] c on a.UserID = c.UserID 
  where c.UserID = 16

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Синтаксис метода (= синтаксис с лямбда-выражениями) обладает большей функциональностью, чем синтаксис запроса.Поэтому я предпочитаю использовать синтаксис метода выше синтаксиса запроса.

Однако есть одно исключение: при объединении трех или более таблиц синтаксис метода выглядит отвратительно, как Себу показал в своем ответе.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 / ...

0 голосов
/ 25 июня 2018
var result= PayoutsOfUser.Join(Payout,
              a=>a.PayoutID,
              b=>b.PayoutID,
              (a,b)=>new{PayoutsOfUser=a,Payout=b})
            .Join(Users,
              a=>a.PayoutsOfUser.UserID,
              c=>c.UserID,
              (a,c)=>new{a.PayoutsOfUser,a.Payout,Users=c})
            .Where(x=>x.Users.UserID==16)
            .Select(x=>new
            {
                 a.PayoutID,
                 b.PayoutName
            }).ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...