Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM Новый топик    Ответить
 LINQ LEFT JOIN с проверкой на NULL  [new]
Георгий Давидович
Member

Откуда:
Сообщений: 349
Вообщем такая задача. Надо перевести SQL код в LINQ запрос.

Select * From Table1 t1
	Left Join Table2 t2 On (t1.Col1 = t2.Col1 Or t2.Col1 Is NULL) And 
		                  (t1.Col2 = t2.Col2 Or t2.Col2 Is NULL)
	Where t2.ID Is Null

Бьюсь уже целый день. Ничего не выходит. Может поможет кто?
25 авг 11, 14:44    [11178471]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
МСУ
Member [заблокирован]

Откуда: http://codearticles.ru
Сообщений: 31089
Попробуйте так:

var x = from t1 in db.Table1s
        join t2 in db.Table2s on new { с1 = t1.Col1, с2 = (int?)null, с3 = t1.Col2, с4 = (int?)null }
            equals new { с1 = t2.Col1, с2 = t2.Col1, с3 = t2.Col2, с4 = t2.Col2 } into t2_join
        from t2 in t2_join.DefaultIfEmpty()
        where t2.ID == null
        select new
        {
            t1,
            t2
        };
25 авг 11, 15:45    [11179149]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
Георгий Давидович
Member

Откуда:
Сообщений: 349
автор
MCY

Спасибо, но код транслируется след. образом

Select * From Table1 t1
	Left Join Table2 t2 On (t1.Col1 = t2.Col1 And t2.Col1 Is NULL) And 
		                  (t1.Col2 = t2.Col2 And t2.Col2 Is NULL)
	Where t2.ID Is Null
25 авг 11, 17:03    [11180035]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
Cat2
Member

Откуда: Petroskoi, Karjala
Сообщений: 145719
Что-то я не увиде разницы между начальным запросом и тем, в который транслируется.

Сам запрос какой-то странный. В результат должны попасть те строки из первой таблице для которых нет связи со второй по кол1 и кол2?

тогда просто:

Select * From Table1 t1
	Left Join Table2 t2 On (t1.Col1 = t2.Col1) And 
		                  (t1.Col2 = t2.Col2)
	Where t2.ID Is Null

Начальный запрос эквивалентен:

Select * From Table1 t1
	Left Join Table2 t2 On (t1.Col1 = t2.Col1) And 
		                  (t1.Col2 = t2.Col2)
	Where t2.ID Is Null  Or t2.Col1 Is NULL Or t2.Col2 Is NULL
Не связи - так все колонки из второй таблице будут NULL и незачем их всех перечислять.
25 авг 11, 18:15    [11180641]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
Георгий Давидович
Member

Откуда:
Сообщений: 349
Надо
25 авг 11, 18:23    [11180707]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
Георгий Давидович
Member

Откуда:
Сообщений: 349
Надо
Select * From Table1 t1
	Left Join Table2 t2 On (t1.Col1 = t2.Col1 Or t2.Col1 Is NULL) And 
		                  (t1.Col2 = t2.Col2 Or t2.Col2 Is NULL)
	Where t2.ID Is Null
Получаю

Select * From Table1 t1
	Left Join Table2 t2 On (t1.Col1 = t2.Col1 And t2.Col1 Is NULL) And 
		                  (t1.Col2 = t2.Col2 And t2.Col2 Is NULL)
	Where t2.ID Is Null

Разница в OR и AND
25 авг 11, 18:26    [11180731]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
МСУ
Member [заблокирован]

Откуда: http://codearticles.ru
Сообщений: 31089
Георгий Давидович
автор
MCY

Спасибо, но код транслируется след. образом

Select * From Table1 t1
	Left Join Table2 t2 On (t1.Col1 = t2.Col1 And t2.Col1 Is NULL) And 
		                  (t1.Col2 = t2.Col2 And t2.Col2 Is NULL)
	Where t2.ID Is Null


Он не транслируется в этот запрос, это Вы сами выдумали.

P.S. Приведите пример с данными в таблицах, в котором сможете продемонстрировать несоответствие выборок через исходный запрос и linq-запрос.
25 авг 11, 20:06    [11181220]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
Георгий Давидович
Member

Откуда:
Сообщений: 349
МСУ
Он не транслируется в этот запрос, это Вы сами выдумали.

P.S. Приведите пример с данными в таблицах, в котором сможете продемонстрировать несоответствие выборок через исходный запрос и linq-запрос.


Хммм... Ну смотрите
[url=]http://s014.radikal.ru/i326/1108/f1/2fcdb8c13dc3.jpg[/url]
25 авг 11, 20:40    [11181318]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
МСУ
Member [заблокирован]

Откуда: http://codearticles.ru
Сообщений: 31089
Георгий Давидович
Хммм... Ну смотрите

А профайлер что говорит?
25 авг 11, 20:47    [11181351]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
Георгий Давидович
Member

Откуда:
Сообщений: 349
При чем тут профайлер?

Вот реальный селект.

[url=]http://i038.radikal.ru/1108/90/6e8ac74f4c7b.png[/url]

У меня возвращатся 1 строка, у вас 2 строки.
25 авг 11, 20:55    [11181383]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
МСУ
Member [заблокирован]

Откуда: http://codearticles.ru
Сообщений: 31089
Георгий Давидович
При чем тут профайлер?

Притом, что только он может показать сгенеренный запрос. Либо используйте Log контекста.
То, что показываете Вы - гавно на постном масле. Не понятно?
25 авг 11, 21:59    [11181527]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
Георгий Давидович
Member

Откуда:
Сообщений: 349
Вот то говно, которое ловит профайлер
SELECT  *
FROM    [Table_1] AS [Extent1]
        LEFT OUTER JOIN [Table_2] AS [Extent2] ON (
                                                                    ( [Extent1].Col1 = [Extent2].Col1 )
                                                                    OR (
                                                                         ( [Extent1].Col1 IS NULL )
                                                                         AND ( [Extent2].Col1 IS NULL )
                                                                       )
                                                                  )
                                                                  AND (
                                                                        [Extent2].Col1 = ( CAST(NULL AS int) )
                                                                        OR [Extent2].Col1 IS NULL
                                                                      )
                                                                  AND (
                                                                        ( [Extent1].Col2 = [Extent2].Col2 )
                                                                        OR (
                                                                             ( [Extent1].Col2 IS NULL )
                                                                             AND ( [Extent2].Col2 IS NULL )
                                                                           )
                                                                      )
                                                                  AND (
                                                                        [Extent2].Col2 = ( CAST(NULL AS int) )
                                                                        OR [Extent2].Col2 IS NULL
                                                                      )
WHERE   [Extent2].[ID] IS NULL

и которое возвращает опять 2 записи на тех же данных, что неверно. Мне нужна 1 запись...
25 авг 11, 23:27    [11181788]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
Верблюд
Member

Откуда: Яженичеловек!!!
Сообщений: 65007
var query = Table1s.Where(x=> !Table2s.Any(y=> (x.Col1 == y.Col1 || y.Col1 == null) && (x.Col2 == y.Col2 || y.Col2 == null)));

query.Dump();
26 авг 11, 00:22    [11181928]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
Верблюд
Member

Откуда: Яженичеловек!!!
Сообщений: 65007
Верблюд
var query = Table1s.Where(x=> !Table2s.Any(y=> (x.Col1 == y.Col1 || y.Col1 == null) && (x.Col2 == y.Col2 || y.Col2 == null)));

query.Dump();


если в Table2.Id not null
26 авг 11, 00:27    [11181936]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
МСУ
Member [заблокирован]

Откуда: http://codearticles.ru
Сообщений: 31089
Георгий Давидович
Вот то говно, которое ловит профайлер

using (var db = new ModelDataContext())
{
    string sql = string.Empty;
    db.Log = new ActionTextWriter(s => sql += s);

    var query = (from t1 in db.Table1s
            join t2 in db.Table2s on new { с1 = t1.Col1, с2 = (int?)null, с3 = t1.Col2, с4 = (int?)null }
                equals new { с1 = t2.Col1, с2 = t2.Col1, с3 = t2.Col2, с4 = t2.Col2 } into t2_join
            from t2 in t2_join.DefaultIfEmpty()
            where t2.ID == null
            select new
            {
                t1,
                t2
            }).ToList();
}

+ говно
SELECT  *
FROM    [Table_1] AS [Extent1]
        LEFT OUTER JOIN [Table_2] AS [Extent2] ON (
                                                                    ( [Extent1].Col1 = [Extent2].Col1 )
                                                                    OR (
                                                                         ( [Extent1].Col1 IS NULL )
                                                                         AND ( [Extent2].Col1 IS NULL )
                                                                       )
                                                                  )
                                                                  AND (
                                                                        [Extent2].Col1 = ( CAST(NULL AS int) )
                                                                        OR [Extent2].Col1 IS NULL
                                                                      )
                                                                  AND (
                                                                        ( [Extent1].Col2 = [Extent2].Col2 )
                                                                        OR (
                                                                             ( [Extent1].Col2 IS NULL )
                                                                             AND ( [Extent2].Col2 IS NULL )
                                                                           )
                                                                      )
                                                                  AND (
                                                                        [Extent2].Col2 = ( CAST(NULL AS int) )
                                                                        OR [Extent2].Col2 IS NULL
                                                                      )
WHERE   [Extent2].[ID] IS NULL

и которое возвращает опять 2 записи на тех же данных, что неверно. Мне нужна 1 запись...


+ Log
SELECT [t0].[Col1],
       [t0].[Col2],
       [t2].[test],
       [t2].[Col1] AS [Col12],
       [t2].[Col2] AS [Col22],
       [t2].[ID]
FROM   [dbo].[Table1] AS [t0]
       LEFT OUTER JOIN (
                SELECT 1 AS [test],
                       [t1].[Col1],
                       [t1].[Col2],
                       [t1].[ID]
                FROM   [dbo].[Table2] AS [t1]
            ) AS [t2]
            ON  ([t0].[Col1] = [t2].[Col1])
            AND ([t2].[Col1] IS NULL)
            AND ([t0].[Col2] = [t2].[Col2])
            AND ([t2].[Col2] IS NULL)
WHERE  [t2].[ID] IS NULL 
       -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1
26 авг 11, 08:53    [11182282]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
МСУ
Member [заблокирован]

Откуда: http://codearticles.ru
Сообщений: 31089
Георгий Давидович, я же Вам говорил, приведите пример заполнения таблиц (инсерты). Будем смотреть, а не ворочать кофейную гущу.
26 авг 11, 08:56    [11182296]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
Cat2
Member

Откуда: Petroskoi, Karjala
Сообщений: 145719
Георгий Давидович
Надо
Select * From Table1 t1
	Left Join Table2 t2 On (t1.Col1 = t2.Col1 Or t2.Col1 Is NULL) And 
		                  (t1.Col2 = t2.Col2 Or t2.Col2 Is NULL)
	Where t2.ID Is Null
Получаю

Select * From Table1 t1
	Left Join Table2 t2 On (t1.Col1 = t2.Col1 And t2.Col1 Is NULL) And 
		                  (t1.Col2 = t2.Col2 And t2.Col2 Is NULL)
	Where t2.ID Is Null
Разница в OR и AND

Прошу прощения, не заметил.
Однако приведенный мною заменяющий запрос, насколько я понял, соответствуют Вашим требованиям. Найти записи в таблице 1, у которых нет соответствия в таблице 2 по ключам.

Я рекомендую Вам переписать автотосгенерированные м запросы, а не нагружать мозг участникам форума запутанными вещами.
26 авг 11, 18:01    [11187537]     Ответить | Цитировать Сообщить модератору
 Re: LINQ LEFT JOIN с проверкой на NULL  [new]
Cat2
Member

Откуда: Petroskoi, Karjala
Сообщений: 145719
МСУ
Георгий Давидович, я же Вам говорил, приведите пример заполнения таблиц (инсерты). Будем смотреть, а не ворочать кофейную гущу.

Так он привел.

http://i038.radikal.ru/1108/90/6e8ac74f4c7b.png

В виде картинки.

Я не умею делать запросы к картинкам.
Но вроде ты более продвинутый . Поделись знаниями, как сделать выборку по картинке в JPG
26 авг 11, 18:12    [11187614]     Ответить | Цитировать Сообщить модератору
Все форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM Ответить