Здравствуйте, Sshur, Вы писали:
S>Update ... from ...? S>Есть ли возможность написать пусть даже простой update без перетаскивания всех строк на клиента? У меня в проекте с линк2sql на каждый update стоит db.ExecuteCommand("UPDATE...");
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Sshur, Вы писали:
S>>Update ... from ...? S>>Есть ли возможность написать пусть даже простой update без перетаскивания всех строк на клиента? У меня в проекте с линк2sql на каждый update стоит db.ExecuteCommand("UPDATE...");
IT>http://bltoolkit.net/Doc.LinqExtensions.ashx#Update_2
IT>Это не Linq 2 SQL, но это Linq.
Доп метод .Update не часть языка. Соответсвенно это не Language INtegrated Query, коими являются запросы типа from e in employes select e.Id. Разве не так?
Методов расширения, которые будут типизированные параметры принимать, можно хоть для DataSet наделать
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, Sshur, Вы писали:
S>>>Update ... from ...? S>>>Есть ли возможность написать пусть даже простой update без перетаскивания всех строк на клиента? У меня в проекте с линк2sql на каждый update стоит db.ExecuteCommand("UPDATE..."); IT>>http://bltoolkit.net/Doc.LinqExtensions.ashx#Update_2 IT>>Это не Linq 2 SQL, но это Linq.
S>Доп метод .Update не часть языка. Соответсвенно это не Language INtegrated Query, коими являются запросы типа from e in employes select e.Id. Разве не так? S>Методов расширения, которые будут типизированные параметры принимать, можно хоть для DataSet наделать
Была бы библиотека c реализацией, а уж найти Language в который подобный Query можно сделать как INtegrated — задача более чем решаемая
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Была бы библиотека c реализацией, а уж найти Language в который подобный Query можно сделать как INtegrated — задача более чем решаемая
Здравствуйте, adontz, Вы писали:
_FR>>Была бы библиотека c реализацией, а уж найти Language в который подобный Query можно сделать как INtegrated — задача более чем решаемая
A>Nemerle?
"Заметьте, не я это предложил"
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Sshur, Вы писали:
S>Доп метод .Update не часть языка. Соответсвенно это не Language INtegrated Query, коими являются запросы типа from e in employes select e.Id. Разве не так?
Не так. Query Comprehension Syntax покрывает едва ли половину всех функций Linq. Из того, что не покрывается: все агрегатные функции (Count, Min, Max, Average), Contains, Any, All, Intersect, Except, Union, Concat, Take, Skip, DefaultIfEmpty, First(OrDefault), Single(OrDefault), ElementAt, наверняка ещё что-то забыл.
S>Методов расширения, которые будут типизированные параметры принимать, можно хоть для DataSet наделать
Для DataSet можно написать чего угодно. Для Linq 2 SQL нельзя написать ничего. Насколько мне известно, расширяемых провайдеров в природе пока не существует, хотя скоро появятся. Но даже если бы они и были, то написание своего расширения задача очень и очень нетривиальная.
Если нам не помогут, то мы тоже никого не пощадим.
S>>Доп метод .Update не часть языка. Соответсвенно это не Language INtegrated Query, коими являются запросы типа from e in employes select e.Id. Разве не так? S>>Методов расширения, которые будут типизированные параметры принимать, можно хоть для DataSet наделать
_FR>Была бы библиотека c реализацией, а уж найти Language в который подобный Query можно сделать как INtegrated — задача более чем решаемая
Угу, напишем свой SQL, с блекджеком и шлю типизацией
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, IT, Вы писали:
AP>>Если интересно могу расписать подробнее что там с LEFT JOIN-ами, но это не выйдет кратко. IT>Будет интересно.
1. Если требуется join-нить несколько таблиц (больше двух), то без query comprehension хреново, потому что вложенные лямбды дают экспоненциальную сложность при компиляции, а писать такие запросы вручную без вложенных лямбд это кошмар. Поэтому единственное спасение query comprehension. Но в C# query comprehension это не просто дополнительный метод, а уже часть языка. Т.е. надо вводить оператор left join на уровне языка.
2. Если взять SQL запросы:
SELECT Bbb.AaaId FROM Aaa INNER JOIN Bbb ON Aaa.A001 = Bbb.B001
SELECT Bbb.AaaId FROM Aaa LEFT JOIN Bbb ON Aaa.A001 = Bbb.B001
И запросить column metadata, например, с помощью метода SqlDataReader.GetSchemaTable, то мы получим, что для столбца Bbb.AaaId в первом случае AllowDBNull=false, а во втором AllowDBNull=true.
Как такое поддержать (естественно, на этапе компиляции) с помощью введения только метода?
3. Если рассмотреть предыдущие пункты в совокупности:
from aaa in Aaa
join bbb in Bbb
on aaa.A001 equals bbb.B001 /*здесь aaa.A001 еще not nullable*/
right join ccc in Ccc
on aaa.A001 equals ccc.C001 /*здесь aaa.A001 еще not nullable*/join ddd in Ddd
on aaa.A001 equals ddd.D001 /*здесь aaa.A001 уже nullable*/select
aaa.A002 /*nullable из-за второго right join-а*/
ссс.С002 /*not nullable*/
Как это всё поддерживать на этапе компиляции? Без изменения языка не обойтись.
Здравствуйте, Alexander Polyakov, Вы писали:
AP>Здравствуйте, IT, Вы писали:
AP>>>Если интересно могу расписать подробнее что там с LEFT JOIN-ами, но это не выйдет кратко. IT>>Будет интересно. AP>1. Если требуется join-нить несколько таблиц (больше двух), то без query comprehension хреново, потому что вложенные лямбды дают экспоненциальную сложность при компиляции, а писать такие запросы вручную без вложенных лямбд это кошмар. Поэтому единственное спасение query comprehension.
Не понял, от чего спасение? query comprehension рассахариваются в такие же вызовы, как писать руками.
AP>Но в C# query comprehension это не просто дополнительный метод, а уже часть языка. Т.е. надо вводить оператор left join на уровне языка.
Непонятно зачем оно нужно.
AP>2. Если взять SQL запросы: AP>
AP>SELECT Bbb.AaaId FROM Aaa INNER JOIN Bbb ON Aaa.A001 = Bbb.B001
AP>SELECT Bbb.AaaId FROM Aaa LEFT JOIN Bbb ON Aaa.A001 = Bbb.B001
AP>
AP>И запросить column metadata, например, с помощью метода SqlDataReader.GetSchemaTable, то мы получим, что для столбца Bbb.AaaId в первом случае AllowDBNull=false, а во втором AllowDBNull=true. AP>Как такое поддержать (естественно, на этапе компиляции) с помощью введения только метода?
Зачем подержать? Можешь сказать как поменяется семантика значений в данном случае?
Что-то есть подозрение что семантика будет закладываться в модель, а не в запрос.
AP>3. Если рассмотреть предыдущие пункты в совокупности: AP>
AP>from aaa in Aaa
AP>join bbb in Bbb
AP> on aaa.A001 equals bbb.B001 /*здесь aaa.A001 еще not nullable*/
AP>right join ccc in Ccc
AP> on aaa.A001 equals ccc.C001 /*здесь aaa.A001 еще not nullable*/
AP>join ddd in Ddd
AP> on aaa.A001 equals ddd.D001 /*здесь aaa.A001 уже nullable*/
AP>select
AP> aaa.A002 /*nullable из-за второго right join-а*/
AP> ссс.С002 /*not nullable*/
AP>
Как это всё поддерживать на этапе компиляции? Без изменения языка не обойтись.
А какой смысл писать руками джоины? Это все можно внести в модель и пользоваться навигационными свойствами, запрос станет однозначнее и короче.
Здравствуйте, IT, Вы писали:
IT>На самом деле это более общая проблема чем LEFT JOIN. Как быть, например, в следующей ситуации?
В твоем примере нет никакой проблемы. Nullability колонок четко содержится в определении класса (типа) Table. А вот в случае LEFT JOIN-на nullability колонок уже не определяется только классами “таблиц”, участвующих в join-е; на nullability колонок оказывает влияние еще сама операция left/right join. Более того, как показано в моем посте выше, одно и тоже выражение aaa.A001 может иметь разную nullability в разных участках одного запроса.
Здравствуйте, Alexander Polyakov, Вы писали:
IT>>На самом деле это более общая проблема чем LEFT JOIN. Как быть, например, в следующей ситуации? AP>В твоем примере нет никакой проблемы. Nullability колонок четко содержится в определении класса (типа) Table.
Вот определение класса:
class Table
{
public int Field1;
public int Field2;
}
Никаких null.
А вот соответсвующий SQL:
SELECT Field1, NULL FROM Table1
UNION
SELECT NULL, Field2 FROM Table1
К классе не nullable, а в жизни nullable.
AP>А вот в случае LEFT JOIN-на nullability колонок уже не определяется только классами “таблиц”, участвующих в join-е; на nullability колонок оказывает влияние еще сама операция left/right join. Более того, как показано в моем посте выше, одно и тоже выражение aaa.A001 может иметь разную nullability в разных участках одного запроса.
И здесь оно разное. Добавь WHERE в любой селект и получишь что тебе надо.
На самом деле всё это ерунда. Проблема есть конечно, но не такая большая.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Вот определение класса:
IT>
IT>class Table
IT>{
IT> public int Field1;
IT> public int Field2;
IT>}
IT>
IT>Никаких null. IT>А вот соответсвующий SQL: IT>
IT>SELECT Field1, NULL FROM Table1
IT>UNION
IT>SELECT NULL, Field2 FROM Table1
IT>
IT>К классе не nullable, а в жизни nullable.
Ты, кажется, не понимаешь про LEFT JOIN.
Попробую объяснить с другой стороны. Если отказаться от LINQ и использовать, скажем, stored procedures или просто запросы и какую-либо тулзу для генерирования классов для result set-ов (которая внутри использует метод типа SqlDataReader.GetSchemaTable), тогда для вот такого запроса:
SELECT Bbb.AaaId FROM Aaa LEFT JOIN Bbb ON Aaa.A001 = Bbb.B001
сгенерируется класс
class QueryResult1
{
public int? AaaId;
}
А для такого запроса:
SELECT Bbb.AaaId FROM Aaa INNER JOIN Bbb ON Aaa.A001 = Bbb.B001
class QueryResult2
{
public int AaaId;
}
Зачем ты выписал SQL запрос, если у тебя LINQ, я не понял. Но если плясать от твоего SQL запроса, то метод SqlDataReader.GetSchemaTable для такого запроса сгенерирует класс:
class Table
{
public int? Field1;
public int? Field2;
}
Вместо генерации, естественно, можно использовать просто верификацию, т.е. и запрос и класс пишутся руками, а тулза лишь проверяет их на совместимость. В твоем примере тулза выдаст ошибку о том, что запрос
SELECT Field1, NULL FROM Table1
UNION
SELECT NULL, Field2 FROM Table1
не совместим с классом:
class Table
{
public int Field1;
public int Field2;
}
Вот что-то подобное и хотелось бы иметь в C#-е -- такую поддержку проверок nullability для LEFT JOIN-ов на этапе компиляции.
Здравствуйте, adontz, Вы писали:
IT>>Я, кажется, не понимаю серьёзности поднятой тобой проблемы. Зачем мне генерировать классы под каждый запрос? A>А разве анонимные типы не генерируются компилятором?
А разве ты не сам определяешь то, что генерирует компилятор?
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>>>Я, кажется, не понимаю серьёзности поднятой тобой проблемы. Зачем мне генерировать классы под каждый запрос? A>>А разве анонимные типы не генерируются компилятором? IT>А разве ты не сам определяешь то, что генерирует компилятор?
Я так понимаю проблема в том, что компилятор либо должен все поля генерировать Nullable (что, даже если плюнуть на производительность, просто неудобно в использовании), либо будут ошибки времени выполнения.
Здравствуйте, adontz, Вы писали:
A>Я так понимаю проблема в том, что компилятор либо должен все поля генерировать Nullable (что, даже если плюнуть на производительность, просто неудобно в использовании), либо будут ошибки времени выполнения.
Компилятор сгенерирует то, что ему скажут. С какой стати он начнёт генерировать без твоего разрешения Nullable? Про ошибки времени выполнения я честно говоря не понял.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
A>>Я так понимаю проблема в том, что компилятор либо должен все поля генерировать Nullable (что, даже если плюнуть на производительность, просто неудобно в использовании), либо будут ошибки времени выполнения. IT>Компилятор сгенерирует то, что ему скажут. С какой стати он начнёт генерировать без твоего разрешения Nullable? Про ошибки времени выполнения я честно говоря не понял.
Как сказать что нужен Nullable в случае outer join: left. right, cross, не суть?
Что будет если в поле не Nullable типа попытаться записать null?