Здравствуйте, VladD2, Вы писали:
VD>Линк был разработан одним из создателей Хакеля и в линке были применены подходы ДСЛ-естроенпия VD>опробированные в хаскеле.
В Haskell eDSL строится на комбинаторах/операторах и ленивости, LINQ же — добавление новой конструкции в язык. Совершенно разные подходы.
VD>Так и делали в HaskellDB. Только DataContext там не было.
+1. В чистом языке DataContext как бы вообще не нужен.
J>>Причем функция process :: Customer -> Customer никакими автомагическими путями в SQL не преобразуется, да и невозможно это в общем случае.
VD>Гы-гы. Ошибаешься. VD>Курим http://haskelldb.sourceforge.net/
Неправда твоя. Query строится вполне определёнными комбинаторами, Customer -> Customer действительно в SQL никак не преобразуется.
VD>Никто не говорит, что ты должен все делать только голым DML встроенным в язык. Но ведь и запись измененных объектов можно сделать на базе DML. Не правда ли?
Здравствуйте, lomeo, Вы писали:
L>Здравствуйте, VladD2, Вы писали:
VD>>Линк был разработан одним из создателей Хакеля и в линке были применены подходы ДСЛ-естроенпия VD>>опробированные в хаскеле.
L>В Haskell eDSL строится на комбинаторах/операторах и ленивости, LINQ же — добавление новой конструкции в язык. Совершенно разные подходы.
Что ты со мной споришь? Ссылку дали. Читай.
И LINQ, и HaskellDB оба основаны на лябдах. Другое дело, что для LINQ был сделан полноценный синтаксис и сам набор примитивов расширили введя OrderBy и GroupBy.
Понятно, что в Хаскеле это было сделано имеющимися срдствами, в C# расширили язык. Ну, и что? В итоге в C# получилось лучше.
VD>>Так и делали в HaskellDB. Только DataContext там не было.
L>+1. В чистом языке DataContext как бы вообще не нужен.
Нет в природе чистых языков. Изменение данных в БД самая что ни на есть императивная операция. И пофигу где это делается в Хаскеле или Шарпе. Просто разные средства применяются. В одном случае нужна монада IO, а во втором нет.
DataContext же — это подход при котором такое изменение делается не явно, а сам DataContext средство объеденить изменения в одну транзакцию. Если бы в Хаскеле выбрали бы такой же пордход, то и аналог DataContext у них появился бы.
VD>>Гы-гы. Ошибаешься. VD>>Курим http://haskelldb.sourceforge.net/
L>Неправда твоя. Query строится вполне определёнными комбинаторами, Customer -> Customer действительно в SQL никак не преобразуется.
Ты почитай, а потом будешь вещать. Они генерирует SQL по EDSL и выполняют его на сервере. 1 в 1 как в линк.
VD>>Никто не говорит, что ты должен все делать только голым DML встроенным в язык. Но ведь и запись измененных объектов можно сделать на базе DML. Не правда ли?
L>Мне эта идея очень нравится.
Если бы были аргументы, то можно было бы хоть что-то сказать. А так... Твои проблемы. Не нравится, так не нравится.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, gandjustas, Вы писали:
G>Я че-то перестал понимать. G>Если в датасете поменять (названия) таблицы на списки сущностей, строки на объекты, то получится тоже самое что и в контексте.
Нет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, gandjustas, Вы писали:
G>>Я че-то перестал понимать. G>>Если в датасете поменять (названия) таблицы на списки сущностей, строки на объекты, то получится тоже самое что и в контексте.
VD>Нет.
Конкретнее?
Здравствуйте, gandjustas, Вы писали:
G>>>Я че-то перестал понимать. G>>>Если в датасете поменять (названия) таблицы на списки сущностей, строки на объекты, то получится тоже самое что и в контексте.
VD>>Нет. G>Конкретнее?
Все наоборот. Если в схеме LINQ выбросить ленивость и датаконтест, то получится что-то вроде типизированного датасета хорошего качества. Важной чертой датасетов является возможность получить данные, передать для обработки в другую область (домен, процесс, сервер), обработать его там, и если это необходимо, вернуть изменения на сервер БД (где их с помощью DML запишут в БД).
Единственное — LINQ всегда возвращает плоский списко, а датасеты могли хранить релияционный набор данных. Но я думаю, что как раз это совершенно не обязательная возможность. В конце концов всегда можно сделать надстройку над плоскими таблицами я-ля датасет (со связями, индексами и т.п.).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, gandjustas, Вы писали:
G>>>>Я че-то перестал понимать. G>>>>Если в датасете поменять (названия) таблицы на списки сущностей, строки на объекты, то получится тоже самое что и в контексте.
VD>>>Нет. G>>Конкретнее?
VD>Все наоборот. Если в схеме LINQ выбросить ленивость и датаконтест, то получится что-то вроде типизированного датасета хорошего качества. Важной чертой датасетов является возможность получить данные, передать для обработки в другую область (домен, процесс, сервер), обработать его там, и если это необходимо, вернуть изменения на сервер БД (где их с помощью DML запишут в БД).
Эта "важная черта" как раз обеспечивается change\identity — трекингом, тем против чего вы боретесь в случае Linq. Только Linq2SQL\EF этот трекинг делают неявно, в отличие от датасетов.
В следующей версии EF будет ObjectSet, который позволит передавать данные в другую область, сейчас можно пользоваться EntityBag.
А вот когда появится DML с помощью Linq — неизвестно, может и не появится вообще.
VD>Единственное — LINQ всегда возвращает плоский списко, а датасеты могли хранить релияционный набор данных. Но я думаю, что как раз это совершенно не обязательная возможность. В конце концов всегда можно сделать надстройку над плоскими таблицами я-ля датасет (со связями, индексами и т.п.).
ИМХО если нужен отсоедиеннный набор данных с реляционными фичами, то лучше использовать локальную БД (sqlce) с любой технологией доступа к данным, и что-нибудь вроде Sync Services для синхронизации.
Здравствуйте, gandjustas, Вы писали:
G>Эта "важная черта" как раз обеспечивается change\identity — трекингом, тем против чего вы боретесь в случае Linq. Только Linq2SQL\EF этот трекинг делают неявно, в отличие от датасетов.
Никакого identity-трекинга датасеты не обеспечивают. По определению.
Что же до change-трекинга, то с некоторой натяжкой можно назвать этим мудреным словом список изменений (diff). Но суть совершенно разная. В датасете всего лишь хранится список изменений исходных данных. Никаких синхронизаций с каким-либо локальным или глобальным кэшем при этом не происходит. Это всего лишь способ обеспечить редактрирование некоторых данных на удаленном компьютере и передачу изменений обратно на сервер.
G>В следующей версии EF будет ObjectSet, который позволит передавать данные в другую область, сейчас можно пользоваться EntityBag.
Это все очень мудрено. А главено на фиг не нужно.
G>А вот когда появится DML с помощью Linq — неизвестно, может и не появится вообще.
Мы по разному смотрим на мир. Ты как наблюдатель. Я как созидатель. Не сделает Майкрософт, сделаем мы сами. Универсальный linq-провайдер уже разрабатывает IT. Докрутим его провайдер и будет делать все что нужно. Там нет каких-то идеологических сложностей.
G>ИМХО если нужен отсоедиеннный набор данных с реляционными фичами, то лучше использовать локальную БД (sqlce) с любой технологией доступа к данным, и что-нибудь вроде Sync Services для синхронизации.
Честно говоря сомневаюсь, что такая функциональность вообще серьезно нужна. Но уж к использованию локальной БД — это точно отношения не имеет. Передать БД по сети нельзя (глупо), а датасет можно (на то он и придуман был).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
L>>В Haskell eDSL строится на комбинаторах/операторах и ленивости, LINQ же — добавление новой конструкции в язык. Совершенно разные подходы. VD>Что ты со мной споришь? Ссылку дали. Читай.
Полагаю, я всё там прочитал гораздо раньше и внимательнее тебя ;-)
VD>И LINQ, и HaskellDB оба основаны на лябдах. Другое дело, что для LINQ был сделан полноценный синтаксис и сам набор примитивов расширили введя OrderBy и GroupBy. VD>Понятно, что в Хаскеле это было сделано имеющимися срдствами, в C# расширили язык. Ну, и что? В итоге в C# получилось лучше.
Просто в Хаскель для того же самого не надо расширять язык :-)
То, что они оба основаны на лямбдах не отменяет того простого факта, что подходы к "DSL-строению" у них разные.
VD>DataContext же — это подход при котором такое изменение делается не явно, а сам DataContext средство объеденить изменения в одну транзакцию. Если бы в Хаскеле выбрали бы такой же пордход, то и аналог DataContext у них появился бы.
Я об identity.
VD>>>Гы-гы. Ошибаешься. VD>>>Курим http://haskelldb.sourceforge.net/ L>>Неправда твоя. Query строится вполне определёнными комбинаторами, Customer -> Customer действительно в SQL никак не преобразуется. VD>Ты почитай, а потом будешь вещать. Они генерирует SQL по EDSL и выполняют его на сервере. 1 в 1 как в линк.
Не поверишь, я этим даже когда то пользовался — это чтобы ты меня десять раз читать не посылал. И — да, они генерируют SQL по eDSL, я с этим спорил?
VD>>>Никто не говорит, что ты должен все делать только голым DML встроенным в язык. Но ведь и запись измененных объектов можно сделать на базе DML. Не правда ли?
Правда.
L>>Мне эта идея очень нравится. VD> Если бы были аргументы, то можно было бы хоть что-то сказать. А так... Твои проблемы. Не нравится, так не нравится.
Влад, ты очень, нет, очень-очень-очень невнимательно читаешь. Посмотри, пожалуйста, выделенное. Из-за этой невнимательности ты приводишь некорректные аргументы. Некорректные аргументы не могут внушать доверие к твоей идее, они даже могут работать против тебя.
С HaskellDB вообще интересная история. Давным-давно мы с тобой спорили о LINQ/Query monad. И сейчас ты сам же посылаешь меня читать про то, о чём я тогда говорил тебе. Хм.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, gandjustas, Вы писали:
G>>Эта "важная черта" как раз обеспечивается change\identity — трекингом, тем против чего вы боретесь в случае Linq. Только Linq2SQL\EF этот трекинг делают неявно, в отличие от датасетов.
VD>Что же до change-трекинга, то с некоторой натяжкой можно назвать этим мудреным словом список изменений (diff). Но суть совершенно разная. В датасете всего лишь хранится список изменений исходных данных. Никаких синхронизаций с каким-либо локальным или глобальным кэшем при этом не происходит. Это всего лишь способ обеспечить редактрирование некоторых данных на удаленном компьютере и передачу изменений обратно на сервер.
Весь "кеш" находится в самом датасете, а в Linq2SQL\EF — в контексте.
Мне обе идеи не нравятся. У датасета нельзя оторвать change-tracking и работать только с данными, а в Linq2SQL\EF нельзя оторвать changetracking от контекста, чтобы можно было граф объектов передавать куда-нить и редактировать.
G>>В следующей версии EF будет ObjectSet, который позволит передавать данные в другую область, сейчас можно пользоваться EntityBag.
VD>Это все очень мудрено. А главено на фиг не нужно.
ObjectSet реализует туже идею что и Dataset только с объектами.
G>>А вот когда появится DML с помощью Linq — неизвестно, может и не появится вообще. VD>Мы по разному смотрим на мир. Ты как наблюдатель. Я как созидатель. Не сделает Майкрософт, сделаем мы сами. Универсальный linq-провайдер уже разрабатывает IT. Докрутим его провайдер и будет делать все что нужно. Там нет каких-то идеологических сложностей.
Я сам хотел сделать что-то подобное, чтобы работало через edm. Но поковырялся в edm, понял насколько оно сырое, решил отложить затею.
Здравствуйте, lomeo, Вы писали:
L>Просто в Хаскель для того же самого не надо расширять язык
Это все замечание? Тогда согласен. Но Шарп же уже расширили. Немерле, например, расширять не пришлось. 3 макроса и золотой ключик у нас в кармане.
L>То, что они оба основаны на лямбдах не отменяет того простого факта, что подходы к "DSL-строению" у них разные.
Подход как раз у них одинаковый. На Шарпе просто воспроизвели обкатанный в Хаскеле подход, но в более чистом виде. На Шарпе тоже можно было нафигачить комбинаторов и довольствоваться тем что получили. Но ребята решили сделать все не абы как а промышленном качестве.
Просто сравни сами запросы и тебе станет все очевидно. На Хаскеле sql-ем и не пахнет. Это какой-то ДСЛ который представляет запросы в виде какого-то АСТ. В Шарпе же реализовали почти SQL.
VD>>DataContext же — это подход при котором такое изменение делается не явно, а сам DataContext средство объеденить изменения в одну транзакцию. Если бы в Хаскеле выбрали бы такой же пордход, то и аналог DataContext у них появился бы.
L>Я об identity.
Что ты identity?
L>Не поверишь, я этим даже когда то пользовался — это чтобы ты меня десять раз читать не посылал. И — да, они генерируют SQL по eDSL, я с этим спорил?
Конечно спорил! Ты прочти свои предыдущие сообщения.
L>>>Мне эта идея очень нравится. VD>> Если бы были аргументы, то можно было бы хоть что-то сказать. А так... Твои проблемы. Не нравится, так не нравится.
L>Влад, ты очень, нет, очень-очень-очень невнимательно читаешь. Посмотри, пожалуйста, выделенное. Из-за этой невнимательности ты приводишь некорректные аргументы. Некорректные аргументы не могут внушать доверие к твоей идее, они даже могут работать против тебя.
Да, есть такое. Извини.
L>С HaskellDB вообще интересная история. Давным-давно мы с тобой спорили о LINQ/Query monad. И сейчас ты сам же посылаешь меня читать про то, о чём я тогда говорил тебе. Хм.
Ну, насчет монад я бы и сейчас поспорил бы. Мне кажется хаскелистам везде монады мерещатся. Понятно, что Хаскеле монады — это единственный способ связать два вычисления в цепочку. Но в других языках есть и другие средства. Выражение "императивный аналог монад" примененное Меером меня вообще порадовало.
ЗЫ
Вообще, о чем мы спорим то? Мне показалось, что ты с чем-то не согласен.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, gandjustas, Вы писали:
G>Весь "кеш" находится в самом датасете, а в Linq2SQL\EF — в контексте.
Нет в датасетах кэша. Это просто данные. Главное отличие от кэша — может существовать множество несинхронизируемых копий.
G>Мне обе идеи не нравятся. У датасета нельзя оторвать change-tracking и работать только с данными,
А что мешает этому? Не используй изменения и все.
G>а в Linq2SQL\EF нельзя оторвать changetracking от контекста, чтобы можно было граф объектов передавать куда-нить и редактировать.
В том-то и проблема.
G>ObjectSet реализует туже идею что и Dataset только с объектами.
Тогда это только другое название.
G>Я сам хотел сделать что-то подобное, чтобы работало через edm. Но поковырялся в edm, понял насколько оно сырое, решил отложить затею.
Вот как раз все эти edm мы отправим в топку. Это путь в сторону Гибернэйта. А мы хотели бы получить нечто-то воде доведенного до ума linq2sql. Задачи: 1) получить независимый от СБУД провйдер, 2) реализовать DML.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, gandjustas, Вы писали:
G>>Весь "кеш" находится в самом датасете, а в Linq2SQL\EF — в контексте. VD>Нет в датасетах кэша. Это просто данные. Главное отличие от кэша — может существовать множество несинхронизируемых копий.
Это вопрос веры. Создайте несколько контекстов и у вам с будет несколько несинхронизированных "кешей".
G>>Мне обе идеи не нравятся. У датасета нельзя оторвать change-tracking и работать только с данными, VD>А что мешает этому? Не используй изменения и все.
Тогда смысл датасета пропадает. Если не изменять данные, то проще работать с графом объектов, чем со слепком слаюотипизированных данных из БД.
G>>а в Linq2SQL\EF нельзя оторвать changetracking от контекста, чтобы можно было граф объектов передавать куда-нить и редактировать. VD>В том-то и проблема.
угу.
G>>ObjectSet реализует туже идею что и Dataset только с объектами. VD>Тогда это только другое название.
Не только, в ObjectSet будут объекты, а не реляционные данные.
G>>Я сам хотел сделать что-то подобное, чтобы работало через edm. Но поковырялся в edm, понял насколько оно сырое, решил отложить затею. VD>Вот как раз все эти edm мы отправим в топку. Это путь в сторону Гибернэйта.
Почему?
VD>А мы хотели бы получить нечто-то воде доведенного до ума linq2sql. Задачи: 1) получить независимый от СБУД провйдер,
Это уже есть, провайдеры EF принимают на вход деревья выражений DbCommandTree, работающих с типами из edm.
Только edm на мой взгляд пока еще очень убого.
Здравствуйте, lomeo, Вы писали:
L>Здравствуйте, VladD2, Вы писали:
VD>>Конечно спорил! Ты прочти свои предыдущие сообщения.
L>Речь шла о Customer -> Customer, из которого ну никак ты не получишь SQL.
Да ну?
string GenerateSetClauseFromExpression<T>(Expression<Func<T, T>> expr)
{
var parameter = expr.Parameters[0];
var memberInit = expr.Body as MemberInitExpression;
return String.Join(", ",
memberInit.Bindings
.OfType<MemberAssignment>()
.Select(a => a.Member.Name + " = " + ExpressionToSql(a.Expression))
.ToArray()
);
}
Dictionary<ExpressionType, string> binaryOps = new Dictionary<ExpressionType, string>()
{
{ExpressionType.Add, "+"},
{ExpressionType.Subtract, "-"},
{ExpressionType.Multiply, "*"},
{ExpressionType.Divide, "/"},
};
string ExpressionToSql(Expression e)
{
var constantExpression = e as ConstantExpression;
if (constantExpression != null)
{
return ToSqlString(constantExpression.Value);
}
try
{
Expression<Func<object>> lambda = Expression.Lambda<Func<object>>(Expression.Convert(e, typeof(object)), new ParameterExpression[0]);
return ToSqlString(lambda.Compile()());
}
catch (Exception)
{
var member = e as MemberExpression;
if (member != null)
{
var param = member.Expression as ParameterExpression;
if (param != null)
{
return (member.Member as System.Reflection.PropertyInfo).Name;
}
}
var binary = e as BinaryExpression;
return ExpressionToSql(binary.Left) + binaryOps[binary.NodeType] + ExpressionToSql(binary.Right);
}
}
string ToSqlString(object o)
{
if (o is string)
{
return"'" + o + "'";
}
else
{
return o.ToString();
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
static void Main(string[] args)
{
var setClause = GenerateSetClauseFromExpression<Person>(p => new Person() { Name = "aaa", Age = p.Age + 1 });
Console.WriteLine("update Persons set {0}", setClause);
}
Здравствуйте, gandjustas, Вы писали:
L>>Речь шла о Customer -> Customer, из которого ну никак ты не получишь SQL. G>Да ну?
Если ты перечитаешь 3-4 поста вверх по ветке, то увидишь, что речь шла о том, что "невозможно это в общем случае". И о том, что за примером того, что это всё таки возможно, VladD2 отослал к HaskellDB. Ты отвечаешь совсем не на то. Невнимательное чтение — источник флейма.
G>Наколеночное решение за 15 минут.
Здравствуйте, lomeo, Вы писали:
L>Речь шла о Customer -> Customer, из которого ну никак ты не получишь SQL.
Я не понимаю почему не о Customer -> string * int или еще о чем-то подобном.
Я не пойму почему из функции Customer -> Customer не получить SQL.
И я вообще не понимаю откуда появилась эта Customer -> Customer.
В общем, мая твоя не потимать.
VD>>Вообще, о чем мы спорим то? Мне показалось, что ты с чем-то не согласен.
L>Я не спорил, поправлял. А так я со всем согласен
Тем более.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Я не понимаю почему не о Customer -> string * int или еще о чем-то подобном.
Ну так речь об UPDATE, насколько я понимаю.
VD>Я не пойму почему из функции Customer -> Customer не получить SQL.
Расскажи как — я знаю только дикие способы вроде сравнения конечного и начального объектов, или передачи объекта с тем же интерфейсом, что и кастомер, но который будет при изменении свойств сохранять эти изменения. У обоих решений -- куча недостатков. Ну, а то, что предложил gandjustas сломается, как только у нас появится логика (ветвление/циклы) или если мы передадим реальную функцию, а не выражение.
Здравствуйте, lomeo, Вы писали:
L>Расскажи как — я знаю только дикие способы вроде сравнения конечного и начального объектов, или передачи объекта с тем же интерфейсом, что и кастомер, но который будет при изменении свойств сохранять эти изменения. У обоих решений -- куча недостатков. Ну, а то, что предложил gandjustas сломается, как только у нас появится логика (ветвление/циклы) или если мы передадим реальную функцию, а не выражение.
Стоп.
Давайте сделаем наоборот, напишите такой Upddate statement (без всякой императивщины), который нельзя выразить в чистом функциональном стиле на любом языке
Вряд ли у вас получится.
Здравствуйте, lomeo, Вы писали:
L>Здравствуйте, gandjustas, Вы писали:
G>>Стоп. G>>Давайте сделаем наоборот
L>А зачем?
Затем что цель именно в этом. Не надо выражать операции какого-либо языка в SQL, надо выразить SQL DML в некоторых конструкциях языка.