Linq to Sql - использование нескольких внутренних объединений с несколькими параметрами - PullRequest
1 голос
/ 21 декабря 2011

До сих пор я видел много ТАКИХ вопросов о множественных внутренних соединениях, но ни один из них не решил мои проблемы.Я пытался выполнить внутреннее объединение для 2 таблиц и подвыбрать в третьей таблице, используя одну из предыдущих таблиц.

Вот код sql:

SELECT 
//It's a lot of select fields here. Nothing really useful to solve the problem 
FROM 
    SCHEDULES
INNER JOIN 
    STATUS
ON
    SCHEDULES.COMPANY              = STATUS.COMPANY          AND 
    SCHEDULES.BANK                 = STATUS.BANK             AND 
    SCHEDULES.PRODUCT              = STATUS.PRODUCT          AND 
    SCHEDULES.IDSTRING             = STATUS.IDSTRING         AND 
    SCHEDULES.RECEIVER       = 'ADMILSONDAMASCENO'     AND
    SCHEDULES.SCHEDULING < GETDATE()                   AND
    SCHEDULES.IDSTRING IN (
        SELECT DISTINCT IDSTRING  FROM DEBTS_BBRASIL WHERE
        DEBITOS_BBRASIL.COMPANY        = SCHEDULES.COMPANY        AND
        DEBITOS_BBRASIL.BANK           = SCHEDULES.BANK           AND
        DEBITOS_BBRASIL.PRODUCT        = SCHEDULES.PRODUCT        AND
        DEBITOS_BBRASIL.IDSTRING       = SCHEDULES.IDSTRING       AND
        DEBITOS_BBRASIL.STATUS         <> 2
)
ORDER BY SCHEDULES.SCHEDULING DESC

И вот чтоя пытался сделать с linq to sql:

 from sched in SCHEDULES
    join status in STATUS
      on new { sched.IDSTRING, sched.COMPANY, sched.BANK, sched.PRODUCT } 
      equals new { status.IDSTRING, status.COMPANY, status.BANK, status.PRODUCT } 
    into schedStats
    from ss in schedStats
    join debt in DEBITOS_BBRASILs
      on new { ss.IDSTRING, ss.COMPANY, ss.BANK, ss.PRODUCT }
      equals new { debt.IDSTRING, debt.COMPANY, debT.BANK, debt.PRODUCT }
    where sched.RECEIVER.Equals("ADMILSONDAMASCENO") && 
                         sched.SCHEDULING <= DateTime.Now && debt.STATUS != 2
    select new ScheduledStatus
    {
      //Lots of properties here
    };

Этот код выше, однако, производит Cross-Join, а затем Inner-Join, что, я уверен, дублирует некоторые результаты.Тестирование первого кода на SqlServer дает 189 результатов, в то время как мой код linq to sql дает 546 результатов.Я не знаю, как воспроизвести один и тот же SQL-код для LINQ-SQL-кода.

Я проверил его оба на linqPad, чтобы быть уверенным.

Ответы [ 2 ]

1 голос
/ 22 декабря 2011

При использовании LINQ to SQL явные объединения обычно не должны использоваться.Если вы установили правильные отношения, у вас должны быть свойства навигации, которые вы можете использовать.С этим запросом будет что-то вроде:

from sched in SCHEDULES
where sched.status.debt != 2;

Если у вас есть внешние ключи в базе данных, свойства навигации автоматически генерируются SqlMetal.exe или дизайнером OR, когда вы отбрасываете две таблицы надизайнерская поверхность.Соотношение между таблицами будет показано строкой (см. Пример ниже).

Sample navigation properties

1 голос
/ 22 декабря 2011

Нашел мой ответ после большого количества «поисков». Мне нужен был подзапрос для выполнения поиска по другой таблице, а не по другому соединению. Использование метода linq to sql Any добилось цели. Вот пост , который мне больше всего помог.

А вот код linq to sql, который перевел мой код TSQL:

    from sched in SCHEDULES
        join status in STATUS
          on new { sched.IDSTRING, sched.COMPANY, sched.BANK, sched.PRODUCT } 
          equals new { status.IDSTRING, status.COMPANY, status.BANK, status.PRODUCT } 
        where sched.RECEIVER.Equals("ADMILSONDAMASCENO") && 
              sched.SCHEDULING <= DateTime.Now && DEBITOS_BBRASILs.Any(dbb=> 
                    dbb.IDSTRING.Equals(sched.IDSTRING) 
                     && dbb.COMPANY.Equals(sched.COMPANY) 
                     && dbb.BANK.Equals(sched.BANK) 
                     && dbb.PRODUCT.Equals(sched.PRODUCT)
                     && dbb.STATUS != 2)
        select new ScheduledStatus
        {
         //Lots of properties here
         };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...