Здравствуйте, IT, Вы писали:
IT>А разве ты не сам определяешь то, что генерирует компилятор?
Смотри, если переписать твой пример вот так:
db.Table.Select(t => new { Field1 = t.Field1, Field2 = new int?() }).Union(
db.Table.Select(t => new { Field1 = new int?(), Field2 = t.Field2 }))
.Select(t => new Table { Field1 = t.Field1, Field2 = t.Field2 })
то будет ошибка компиляции в третьей строчке (уже в текущей версии C#).
Аналогично для LEFT JOIN
from aaa in Aaa
left join bbb in Bbb
on aaa.A001 equals bbb.B001
select new { bbb.B001, bbb.B002 };
в анонимном класса поля B001 и B002 должны быть nullable даже, если изначальные поля Bbb.B001 и Bbb.B002 not nullable.
Здравствуйте, Alexander Polyakov, Вы писали:
AP>Здравствуйте, IT, Вы писали:
IT>>А разве ты не сам определяешь то, что генерирует компилятор? AP>Смотри, если переписать твой пример вот так: AP>db.Table.Select(t => new { Field1 = t.Field1, Field2 = new int?() }).Union( AP>db.Table.Select(t => new { Field1 = new int?(), Field2 = t.Field2 })) AP>.Select(t => new Table { Field1 = t.Field1, Field2 = t.Field2 }) AP>то будет ошибка компиляции в третьей строчке (уже в текущей версии C#).
AP>Аналогично для LEFT JOIN AP>from aaa in Aaa AP>left join bbb in Bbb AP>on aaa.A001 equals bbb.B001 AP>select new { bbb.B001, bbb.B002 }; AP>в анонимном класса поля B001 и B002 должны быть nullable даже, если изначальные поля Bbb.B001 и Bbb.B002 not nullable.
Коме должны?
Если логика обрабатывающая результаты запроса опирается на не_null значение колонки, то упадет в любом случае. Если колонка может быть nullable, то это лучше всего описать явно в самом linq запросе, без неявной генерации nullable значений.
Здравствуйте, gandjustas, Вы писали:
G>Если колонка может быть nullable, то это лучше всего описать явно в самом linq запросе, без неявной генерации nullable значений.
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, gandjustas, Вы писали:
G>>Если колонка может быть nullable, то это лучше всего описать явно в самом linq запросе, без неявной генерации nullable значений.
A>Это называется "костыли".
А вариант править семантику Linq просто потому что в SQL такое поведение? В SQL вообще дофигища неявных преобразований, все в .NET тащить? А сколько диалектов этого SQL еще...
Все равно все упрется в семантику тех данных, которые достаются из базы. Если приходит nullable, а требуется не nullable, то придется ставить подпорки чтобы все заработало.
Здравствуйте, Alexander Polyakov, Вы писали:
IT>>А разве ты не сам определяешь то, что генерирует компилятор? AP>Смотри, если переписать твой пример вот так: AP>db.Table.Select(t => new { Field1 = t.Field1, Field2 = new int?() }).Union( AP>db.Table.Select(t => new { Field1 = new int?(), Field2 = t.Field2 })) AP>.Select(t => new Table { Field1 = t.Field1, Field2 = t.Field2 }) AP>то будет ошибка компиляции в третьей строчке (уже в текущей версии C#).
Ошибка будет раньше.
AP>Аналогично для LEFT JOIN AP>from aaa in Aaa AP>left join bbb in Bbb AP>on aaa.A001 equals bbb.B001 AP>select new { bbb.B001, bbb.B002 }; AP>в анонимном класса поля B001 и B002 должны быть nullable даже, если изначальные поля Bbb.B001 и Bbb.B002 not nullable.
Это всё решается.
from aaa in Aaa
left join bbb in Bbb
on aaa.A001 equals bbb.B001
select new
{
// если тебе нужен весь объект, то он будет null
bbb,
// если отдельное поле
B001 = bbb == null ? (int?)null : bbb.B001,
B002 = bbb == null ? (int?)null : bbb.B002
};
Как юы ты решал аналогичную проблему, если бы писал код для Linq 2 Objects? Вот так же делай и для Linq 2 SQL и всё получится.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, gandjustas, Вы писали:
G>А вариант править семантику Linq просто потому что в SQL такое поведение? В SQL вообще дофигища неявных преобразований, все в .NET тащить? А сколько диалектов этого SQL еще... G>Все равно все упрется в семантику тех данных, которые достаются из базы. Если приходит nullable, а требуется не nullable, то придется ставить подпорки чтобы все заработало.
outer join не имеет большого отношения именно к SQL. Это достаточно понятная процедура над множествами сама по себе.
Здравствуйте, IT, Вы писали:
A>>Как сказать что нужен Nullable в случае outer join: left. right, cross, не суть? IT>Пример такой ситуации можешь привести?
Пример чего, right outer join? Вот есть right join, как сказать что связываемые поля должны (или не должны) быть nullable.
A>>Что будет если в поле не Nullable типа попытаться записать null? IT>Как минимум запишется default(T).
Здравствуйте, adontz, Вы писали:
A>>>Как сказать что нужен Nullable в случае outer join: left. right, cross, не суть? IT>>Пример такой ситуации можешь привести?
A>Пример чего, right outer join? Вот есть right join, как сказать что связываемые поля должны (или не должны) быть nullable.
Зачем так много говорить, напиши код и мы его разберём.
A>>>Что будет если в поле не Nullable типа попытаться записать null? IT>>Как минимум запишется default(T).
A>Для value типов это весьма некорректно.
Да ладно.
class A
{
public int Field1;
public int Field2;
}
new A { Field1 = 1 };
Корректно?
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, adontz, Вы писали:
A>outer join не имеет большого отношения именно к SQL. Это достаточно понятная процедура над множествами сама по себе.
И как "проблему", о которой вы тут так долго рассказываете, решается в случае с множествами?
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
A>>Пример чего, right outer join? Вот есть right join, как сказать что связываемые поля должны (или не должны) быть nullable. IT>Зачем так много говорить, напиши код и мы его разберём.
Игорь, зачем тебе код, что тебе не ясно? В результате исполнения right join некоторые столбцы в некоторых строках могут быть равны NULL. Тебе нужен код подтверждающий это утверждение?
A>>Для value типов это весьма некорректно. IT>Да ладно.
Ну если должно быть null, а получилось 0, то да, потому что, очевидно, null != 0.
Здравствуйте, IT, Вы писали:
A>>outer join не имеет большого отношения именно к SQL. Это достаточно понятная процедура над множествами сама по себе. IT>И как "проблему", о которой вы тут так долго рассказываете, решается в случае с множествами?
Здравствуйте, adontz, Вы писали:
A>>>Пример чего, right outer join? Вот есть right join, как сказать что связываемые поля должны (или не должны) быть nullable. IT>>Зачем так много говорить, напиши код и мы его разберём. A>Игорь, зачем тебе код, что тебе не ясно? В результате исполнения right join некоторые столбцы в некоторых строках могут быть равны NULL. Тебе нужен код подтверждающий это утверждение?
Рома, ты не рассуждай, а напиши пример и всё сразу станет ясно. Зачем теоретизировать, если всё легко можно проверить и продемонстрировать на практике.
A>>>Для value типов это весьма некорректно. IT>>Да ладно. A>Ну если должно быть null, а получилось 0, то да, потому что, очевидно, null != 0.
Давай код, без кода я не понимаю о чём ты.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, adontz, Вы писали:
A>>>outer join не имеет большого отношения именно к SQL. Это достаточно понятная процедура над множествами сама по себе. IT>>И как "проблему", о которой вы тут так долго рассказываете, решается в случае с множествами? A>Там проблемы нет, поэтому никак.
Ты хочешь сказать, что у одного и того же Linq запроса, но для разных типов источника будет разная семантика?
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, adontz, Вы писали:
A>>>outer join не имеет большого отношения именно к SQL. Это достаточно понятная процедура над множествами сама по себе. IT>>И как "проблему", о которой вы тут так долго рассказываете, решается в случае с множествами? A>Там проблемы нет, поэтому никак.
Уверен?
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Ты хочешь сказать, что у одного и того же Linq запроса, но для разных типов источника будет разная семантика?
Нет, я о другом говорил, но и это тоже верно.
CREATE TABLE A
(
[ID] INT IDENTITY PRIMARY KEY NOT NULL,
[Length] INT NOT NULL
)
CREATE TABLE B
(
[ID] INT IDENTITY PRIMARY KEY NOT NULL,
[Weight] INT NOT NULL
)
SELECT
[A].[Length],
[B].[Weight]
FROM
[A]
RIGHT JOIN
[B] ON [B].[ID] = [A].[ID]
Очевидно что
1) Weight в выборке может быть NULL, хотя столбец Weight в таблице B помечен NOT NULL.
2) Может ли Length быть NULL зависит от структуры таблицы, а не от запроса.
Со второй проблемой можно более или менее разобраться при генерации Linq обёртки для базы данных. Первая проблема существенно сложнее. Скажем следующий запрос тоже содержит RIGHT JOIN, но Weight не может быть NULL.
SELECT
[A].[Length],
ISNULL([B].[Weight], 0) AS [Weight]
FROM
[A]
RIGHT JOIN
[B] ON [B].[ID] = [A].[ID]
Ну и ещё запрос для поражения психики
SELECT
[A].[Length],
[B].[Weight]
FROM
[A]
RIGHT JOIN
[B] ON [B].[ID] = [A].[ID]
WHERE
[B].[Weight] IS NOT NULL
Здравствуйте, adontz, Вы писали:
IT>>Ты хочешь сказать, что у одного и того же Linq запроса, но для разных типов источника будет разная семантика? A>Нет, я о другом говорил, но и это тоже верно.
A>
A>SELECT
A> [A].[Length],
A> [B].[Weight]
A>FROM
A> [A]
A>RIGHT JOIN
A> [B] ON [B].[ID] = [A].[ID]
A>
A>Очевидно что A>1) Weight в выборке может быть NULL, хотя столбец Weight в таблице B помечен NOT NULL.
Запиши теперь соответствующее выражение на Linq.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
A>>1) Weight в выборке может быть NULL, хотя столбец Weight в таблице B помечен NOT NULL. IT>Запиши теперь соответствующее выражение на Linq.
А причём тут выражение? Речь об анонимном типе который будет использоваться для представления столбца результата.
Здравствуйте, adontz, Вы писали:
A>>>1) Weight в выборке может быть NULL, хотя столбец Weight в таблице B помечен NOT NULL. IT>>Запиши теперь соответствующее выражение на Linq. A>А причём тут выражение? Речь об анонимном типе который будет использоваться для представления столбца результата.
Ну так запиши его.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
A>>>>1) Weight в выборке может быть NULL, хотя столбец Weight в таблице B помечен NOT NULL. IT>>>Запиши теперь соответствующее выражение на Linq. A>>А причём тут выражение? Речь об анонимном типе который будет использоваться для представления столбца результата. IT>Ну так запиши его.