LINQ to Entity: несколько условий соединения - PullRequest
32 голосов
/ 14 октября 2011

Есть множество постов, касающихся LINQ и нескольких объединений.Однако я не нашел решения для объединения, которое я хотел бы сделать.

Эквивалент SQL будет выглядеть примерно так:

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;

Вот один из многочисленных запросов linq, которые я 'я попытался

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......

Как я могу добавить дополнительные условия даты и удаленного флага?Если я использую условия. Где, то это рассматривается как внутреннее соединение, а не как левое соединение.

Ответы [ 4 ]

51 голосов
/ 14 октября 2011

Другой способ может быть как

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}
15 голосов
/ 14 октября 2011

LINQ поддерживает как синтаксис объединения, так и более старый синтаксис ANSI-82 WHERE. Используя позже, вы можете делать то, что вы ищете на внутреннем соединении с

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 ???;

Для внешнего объединения я предпочитаю синтаксис, использующий гибрид where и выбираю многие. (Поймите, что порядок в запросе LINQ не должен имитировать то, что вы делаете в SQL, и порядок более гибкий.)

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 ???;
2 голосов
/ 30 сентября 2017

У меня была проблема с именованием свойств в анонимном объекте:

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();

Компилятор был недоволен, поэтому приведенный выше ответ помогает мне выяснить, в чем дело, и вот мое рабочее решение.Мне понадобилось некоторое время, чтобы найти глупую ошибку :):

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();
1 голос
/ 14 октября 2011

Не могли бы вы просто отфильтровать 1-й набор результатов вторым запросом?

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 ...

Будет ли это работать?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...