Здравствуйте, MxKazan, Вы писали:
IT>>В некотором смысле первый. Дело в том, что преобразованием имени класса в имя поля теперь занимается сам компилятор. Ранее это был ручной или генерируемый код. MK>А какая в сущности разница?
Комрилятор знает больше. Сгенерированная строковая константа для компилятора всё так же остаётся константой. А поле/свойство класса — это ещё и принадлежность к определённому классу. В принципе, precompile-time генератция может многое, но у неё свои козявки. Идеал же вообще ещё не достигнут, но уже возможен. Так, например, уже сегодня вполне возможно на Немерле генерировать необходимую метаинформацию непосредственно из БД в компайл-тайм
MK>Намёк ясен. Но он не совсем применим к Linq-To-Sql, уж слишком специфично, я написал чего не хватает. Видно и Microsoft это понимает, потому и есть Entity Framework. А проблема с DELETE похоже не имеет простого решения.
По мне, так EF — это чистый маркетинг. Наш ответ Хайберлену. Есть же в конце концов и другие невостребованные технологии у MS вроде того же WWF. Будет ещё одна.
MK>Ну вот, например, мне хотелось обновлять объекты в БД так, чтобы генерируемый Sql запрос не проверял изменение остальных полей (имеется ввиду concurrency). Приходилось ручками проставлять почти всем полям класса UpdateCheck в Never. Поменял поле, перегенерил класс и опять давай проставлять. Справедливости ради скажу, это скорее следует отнести к недостаткам Студии.
То о чём ты говоришь если это так, то это ошибки в дизайне. Я не хочу, чтобы компьютер за меня думал. Машина не должна думать, машина должна ездить. Куда скажу, туда и поехала. Тут в соседней ветке об этом уже на 400 сообщений нафлеймили, доказывая, что в хайбернейте LL это очень полезно. Вот такими спецэфектами потом приходится расплачиваться.
IT>>Linq 2 Objects внёс декларативность. Т.е. теперь я пишу что я хочу получить, а не как. В результате вместо кучи циклов с перебором списков и словарей у меня декларативная конструкция. MK>Это понятно, про ФП я читал. Но не очень понятно в чем конкретная новизна по памяти? Речь о локальности данных?
О декларативности работы с данными. Давай рассмотрим пример, может быть так понятней будет. Пример возьмём не очень сложный, но и не самый простой, т.к. на простых примерах вся мощь линка не так проявляется.
Возьмём финансовую задачку. Допустим у нас есть провайдеры, которые тратят бабло и есть получатели, на которых это бабло списывается. С провайдеров деньги списываются через аккаунты в соответствии с определёнными процентами. Например, провайдер '1111' списывает 20% на аккаунт 'AAAA' и 80% на аккаунт 'BBBB'. Получатели получают свою долю тоже через аккаунты, по такому же принципу, т.е., например, получатель '8888' получает 40% с аккаунта 'AAAA' и 60% с аккаунта 'BBBB'. Наша задача получить массив процентов, в котором будет указано, что провайдер '1111' списывает через аккаунт 'AAAA' столько-то процентов на '8888'.
Ниже приведён код. Метод CalcPercents делает эту работу с помощью linq, метод CalcPercents2 в исполнении C# 2.0.
using System;
using System.Linq;
using System.Collections.Generic;
namespace ConsoleApplication
{
class Program
{
class ProvidingVolume
{
public string Provider;
public string Account;
public double Volume;
}
class ReceivingVolume
{
public string Receiver;
public string Account;
public double Volume;
}
class Percent
{
public string Provider;
public string Receiver;
public string Account;
public double Value;
}
static Dictionary<string, List<Percent>> CalcPercents(
ProvidingVolume[] providingVolumes, ReceivingVolume[] receivingVolumes)
{
var percents =
from percent in
from prov in
from p in providingVolumes
group p by p.Provider into pg
let total = pg.Sum(v => v.Volume)
from pp in pg
select new { pp, total }
join rec in
from r in receivingVolumes
group r by r.Account into rg
let total = rg.Sum(v => v.Volume)
from rr in rg
select new { rr, total }
on prov.pp.Account equals rec.rr.Account
select new Percent
{
Provider = prov.pp.Provider,
Receiver = rec.rr.Receiver,
Account = prov.pp.Account,
Value = prov.pp.Volume / prov.total * rec.rr.Volume / rec.total
}
group percent by percent.Provider;
return percents.ToDictionary(p => p.Key, p => p.ToList());
}
static Dictionary<string, List<Percent>> CalcPercents2(
ProvidingVolume[] providingVolumes, ReceivingVolume[] receivingVolumes)
{
Dictionary<string, List<ProvidingVolume>> providingGroup = new Dictionary<string,List<ProvidingVolume>>();
foreach (ProvidingVolume pv in providingVolumes)
{
List<ProvidingVolume> p;
if (!providingGroup.TryGetValue(pv.Provider, out p))
{
p = new List<ProvidingVolume>();
providingGroup[pv.Provider] = p;
}
p.Add(pv);
}
Dictionary<string, List<ReceivingVolume>> receivingGroup = new Dictionary<string,List<ReceivingVolume>>();
foreach (ReceivingVolume rv in receivingVolumes)
{
List<ReceivingVolume> r;
if (!receivingGroup.TryGetValue(rv.Account, out r))
{
r = new List<ReceivingVolume>();
receivingGroup[rv.Account] = r;
}
r.Add(rv);
}
Dictionary<string, double> receivingSum = new Dictionary<string,double>();
foreach (List<ReceivingVolume> list in receivingGroup.Values)
{
double sum = 0;
foreach (ReceivingVolume rv in list)
sum += rv.Volume;
receivingSum[list[0].Account] = sum;
}
Dictionary<string, List<Percent>> percents = new Dictionary<string,List<Percent>>();
foreach (List<ProvidingVolume> list in providingGroup.Values)
{
double sum = 0;
foreach (ProvidingVolume pv in list)
sum += pv.Volume;
foreach (ProvidingVolume pv in list)
{
List<ReceivingVolume> rv;
if (receivingGroup.TryGetValue(pv.Account, out rv))
{
foreach (ReceivingVolume r in rv)
{
Percent percent = new Percent();
percent.Provider = pv.Provider;
percent.Receiver = r.Receiver;
percent.Account = pv.Account;
percent.Value = pv.Volume / sum * r.Volume / receivingSum[r.Account];
List<Percent> ps;
if (!percents.TryGetValue(percent.Provider, out ps))
{
ps = new List<Percent>();
percents.Add(percent.Provider, ps);
}
ps.Add(percent);
}
}
}
}
return percents;
}
static void Main(string[] args)
{
var providingVolums = new []
{
new ProvidingVolume { Provider = "1111", Account = "AAAA", Volume = 20 },
new ProvidingVolume { Provider = "1111", Account = "BBBB", Volume = 80 },
new ProvidingVolume { Provider = "2222", Account = "AAAA", Volume = 30 },
new ProvidingVolume { Provider = "2222", Account = "BBBB", Volume = 70 },
};
var receivingVolumes = new []
{
new ReceivingVolume { Receiver = "8888", Account = "AAAA", Volume = 40 },
new ReceivingVolume { Receiver = "8888", Account = "BBBB", Volume = 60 },
new ReceivingVolume { Receiver = "9999", Account = "AAAA", Volume = 50 },
new ReceivingVolume { Receiver = "9999", Account = "BBBB", Volume = 50 },
};
var percents = CalcPercents(providingVolums, receivingVolumes);
foreach (var ps in percents.Values)
foreach (var p in ps)
Console.WriteLine("{0} {1} {2} {3}", p.Provider, p.Receiver, p.Account, p.Value);
percents = CalcPercents2(providingVolums, receivingVolumes);
foreach (var ps in percents.Values)
foreach (var p in ps)
Console.WriteLine("{0} {1} {2} {3}", p.Provider, p.Receiver, p.Account, p.Value);
}
}
}
Обрати внимание, кода на линке в 3 раза меньше и он декларативен, в отличии от императивщины на C# 2.0. А если учесть, что таких вычислений у меня в коде пачками, то выгода linq более чем очевидна.
MK>Но вообще, IT, я бы хотел еще раз обозначить, что я принципе не против Linq. Хотелось бы просто понимать реальную необходимость этого, реальные плюсы, а не просто как "игрушка для этюдов". Разве это есть гуд, требовать "что", не понимая "как"?
Но ты же не говоришь SQL серверу как именно выполнять запросы? Ты говоришь, хочу то-то и то-то, а он уже сам читает с диска или из кеша, оптимизирует запросы и занимается прочими 'как'.
Неясность изложения обычно происходит от путаницы в мыслях.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Константин Л., Вы писали:
КЛ>Как вам язычок? Возможности? Lazy eval.? Closures? Правила explicit/implicit conv. (особенно для типов-параметров generics)? А learning curve? Размер стандарта?
КЛ>пс: каждый день, когда наталкиваюсь на этюды nikov'а в ветке .net, ощущение того, что растет второй c++, укрепляется в моем мозгу. мне становится отчетливо понятно, что чтобы узнать этот язык хорошо и использовать его полноценно, мне нужно потратить еще кучу времени. c# 1.1 был довольно прост, чтобы не заглядывать в lang spec. не подумайте, что я собираюсь поднять панику, просто интересно, что кто думает по этому поводу.
Согласен с p.s. Тоже укрепляюсь в подобном мнении. К сожалению.
На мой взгляд, реальным плюсом со времен C# 1.1 явились только generic'и причем без implicit.
Особенно меня огорчают extension methods. Интересная вещь, неплохо расширившая функциональность коллекций. Но! Но ведь это абсолютное нарушение концепции ООП! Это же фактически возврат к процедурному программированию. Поддавшись соблазну, ввел в проекте несколько "расширетелей", пользовались ими некоторое время. И всё же вернулись к типичной конструкции static helper'ов.
Подстановка типов для generic'ов. Ну зачем это? Кому оно необходимо? Зато результат — поди догадайся что вызовится. Либо конкретно знать стандарт, либо сидеть гадать — дай Бог, чтобы не на кофейной гуще. Интересно, прикольно, ничего не имею против этюдов, но на практике это скорее зло, чем благо.
А еще я бы убил yield return
P.S. Тем не менее, если оставить сам C# и посмотреть в целом на Framework, то очень радует развитие. Особенно WPF — давно жаждал такого.
Здравствуйте, IT, Вы писали:
IT>Ядерная бомба к мейнстриму отношения не имеет. В мейнстриме есть только одно оружие массового поражения — технология Copy&Paste.
Фи, как пошло. В философском обществе так не выражаются! Тут говорят clipboard inheritance.
Здравствуйте, EvilChild, Вы писали:
EC>Здравствуйте, Константин Л., Вы писали:
КЛ>>мне он кажется слишком сложным, а вам? EC>Сложным в каком месте? EC>Он же существенно проще в освоении, чем C++.
Интересное мнение. Хотя с C# я не работал, читая осуждения на форумах, у меня складывалось впечатление, что он сложнее С++. По крайней мере, там больше различных фитч. И не удивительно. Ведь у C# в отличие от C++ нет коммитета стандартизации — его разрабатывают в пределах одной компании, а следовательно изменения в язык могут вноситься быстрее.
Да, и чем, кстати, С++ сложен? ИМХО там всё довольно просто.
Здравствуйте, MxKazan, Вы писали:
MK>Вопрос то не в этом. Пока что большинство аргументов "за" выглядят примерно так: "появилась новая фича, значит она точно необходима и ей нужно пользоваться". MK>Не опровергая её необходимости, просто хотелось бы увидеть реальные примеры, в которых четко обозначено "было так, не нравилось потому то", "сделал по новому и это решило то-то".
Ну например. Возьмем простой пример. Просуммировать список чисел
var someList = new int {1,2,3,4,5};
var sum = 0;
foreach var x in someList
sum += x
Идея какая такой операции. Пробежать по всем элементам списка и сложить все в сумму.
То бишь аккумулировать результат.
Допустим нам понадобилось сделать умножение.
Проще простого
var sum = 1;
foreach var x in someList
sum *= x
И что видно ? Видно дублирование кода. Отличие только в начальном значении суммы и функции, которая будет применяться на каждом шаге.
Хорошо было бы иметь возможность указывать только эту информацию, без того, чтобы каждый раз писать foreach
Итак пишем функцию
public A Accumulate<A,I>(A accum, Func<A, I, A> fun, List<I> list)
{
foreach (var x in list)
{
accum = fun(x, accum);
}
return accum;
}
// а вот так используемvar sum2 = Accumulate<int, int>(0, (s, x) => s + x);
Мы теперь можно чувствовать себя крутым. Мы абсрагировали способ обхода коллекции (foreach) от операций которые будут выполняться на каждом шаге. Уберутся ненужные дублирования и т.п.
Но это ощущение быстро рассеивается поскольку в C# 3.0 наша доморощенная Accumulate уже есть
var sum = l.Aggregate(0, (s, x) => s + x);
А в f#
оно вообще будет выглядеть как
let sum = foldl (+) 0 someList
И все эти функции появившиеся в третьем шарпе злостные баяны в ФП мире, которые по чуть-чуть перетягиваются в мейнстрим. И для того, чтобы понять какие возможности они открывают, надо глядеть на функциональные языки.
Такие дела.
Здравствуйте, MxKazan, Вы писали:
MK>Не-не-не, так дело не пойдёт. Есть конкретная задача, я её привел в теме, куда ведет ссылка. Прошу, выдайте мне решение. Я хочу удалить объекты из базы, просто по какому-то критерию.
Один раз напиши процедуру удаления и впоследствии пользуйся ею.
IT>>>>2. linq 2 objects принципиально изменил способы обработки данных в памяти. MK>>>Так. Я видимо не в теме. А что принципиального нового linq 2 objects внёс по части "способы обработки данных в памяти"?
IT>>>>3. Возможность работать в функциональном стиле с человеческим лицом. MK>>>Честно говоря, никогда не страдал от отсутствия подобного в C#
G>>Вы действительно не в тебе, были бы в теме — оценили бы преимущества. MK>Отмахнуться — это удобно. А ответить на вопрос?
Ответить прямо? ОК, но не обижайся пожалуйста.
Ты не обладаешь достаточными знаниями, чтобы оценить то что тебе дали в руки.
Подробнее об этом написано здесь (Парадокс Блаба)
Я могу только описать тебе те преимущества которые ты получишь после освоения функционального стиля программирования и понимания (осознания) всех концепций которые с ним связаны.
Освоив ФП ты сможешь писать код обработки коллекций в несколько раз более кратко. При этом код будет содержать в несколько раз меньше ошибок. Людям знакомые с ФП будет в несколько раз проще читать твой код, а значит его в несколько раз будет проще поддерживать.
Кроме того, если ты проникнешся функциональным подходом, то сможешь смотреть на решение многих задач подругому, на намного более абстрактном уровне.
Для того чтобы воспользоваться преимуществами неизвестной тебе парадигмы нужно сделать немалое напряжение, чтобы понять ее. Проблема в том, что для этого обычно нужно менять мировозрение. Простые, казалось бы, концепции просто не втискиваются в рамки императивного мышления.
. Прочитай ее когда она появится на сайте или если в твоих руках окажется 2-ой номер RSDN Magazine.
G>>ЗЫ. Я подобное мнение видел у прожженых C++ников, которые впоследствие перешли на C#. MK>Можно расслабиться и спокойно общаться. Мой профессиональный опыт — 3 года сплошного C#. Никакого C++.
Откровенно говоря тем хуже для тебя. 3 года — это совсем малый срок для нашей профессии, а ты уже становишься ретроградом и отказываешься воспринимать новые (для тебя) знания.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Lloyd, Вы писали:
L>Это всего лишь говорит о том, что при работе через DataContext, не нужно работать в обход него. Проблемы будут неминуемы.
Это всего лишь говорит о том, что identity tracking несовместим с 75% DML. Тут я совершенно согласен — нужно выбирать что-то одно: либо identity tracking либо 75% DML. L>А поэтому и нет необходимости delete по expression-у в DataContext-е.
Логика на высоте. "Новая помада не подошла к цвету машины, поэтому я пошла пешком".
Я всё еще не вижу причин, по которой ты считаешь identity tracking заметно лучше, чем прямое отображение insert/update/delete в SQL.
Судя по переписке в другой ветке, твоя ментальная модель работы с данными именно такая: "загрузить-изменить-записать". Причем последнюю часть пусть думает DataAdapter, у него работа такая. Это радикально отличается от идеологии SQL; датаадаптер в датасетах и идентити трэкинг в линке пытаются натянуть идеологию "работы через курсор", привычную по Delphi, Access, FoxPro и прочим технологиям восьмидесятых, на запрос-ориентированную клиент-серверную технологию SQL.
Вся идея SQL — в том, что нет такой операции "поредактировать результат запроса". Есть update table. Это совсем не то же самое.
Как я могу поапдейтить результат запроса select student, avg(mark) from ... group by student?
В update table я прямо указываю, какие колонки я хочу поредактировать, и зачем.
Датаадаптер пытается вычислить за меня последовательность действий, которые я имел в виду. Иногда ему это удается. Но принципиальная проблема как раз в том, что выразительность семантики "сохранить объект" недостаточна. Вот было бы наоборот — было бы хорошо. Точно так же как сам update в sql не требует указывать подробности на уровне файлов, любая механика поверх SQL должна по идее нас изолировать от несущественных подробностей. Увы, пока что все эти припрыгивания изолируют нас от существенных подробностей.
L>ЗАИЯ
ЗАпросы Интегрированные в Язык = Language-INtegrated Query
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, VoidEx, Вы писали:
VE>Оружие Джедаев — это такая светящаяся палка, которая на раз сносится мейнстримовой ядерной бомбой вместе с самими Джедаями?
Ядерная бомба к мейнстриму отношения не имеет. В мейнстриме есть только одно оружие массового поражения — технология Copy&Paste.
Если нам не помогут, то мы тоже никого не пощадим.
Как вам язычок? Возможности? Lazy eval.? Closures? Правила explicit/implicit conv. (особенно для типов-параметров generics)? А learning curve? Размер стандарта?
пс: каждый день, когда наталкиваюсь на этюды nikov'а в ветке .net, ощущение того, что растет второй c++, укрепляется в моем мозгу. мне становится отчетливо понятно, что чтобы узнать этот язык хорошо и использовать его полноценно, мне нужно потратить еще кучу времени. c# 1.1 был довольно прост, чтобы не заглядывать в lang spec. не подумайте, что я собираюсь поднять панику, просто интересно, что кто думает по этому поводу.
Здравствуйте, Roman Odaisky, Вы писали:
RO>Фамилия у него, насколько я понимаю, датского происхождения (Trølsen).
Кстати, я живу в Дании, и могу сказать, что в русском языке нет буквы точно передающей датское 'ø'. Самым похожим аналогом мне кажется именно 'oe', при условии если произносить их очень слитно, не как 'о-йе'.
Здравствуйте, Константин Л., Вы писали:
КЛ>Как вам язычок?
Супер КЛ> Возможности?
Супер КЛ>Lazy eval.? Closures? Правила explicit/implicit conv. (особенно для типов-параметров generics)?
А что раньше не было разве? Начиная со второго C# все это было. КЛ>А learning curve? Размер стандарта?
КЛ>пс: каждый день, когда наталкиваюсь на этюды nikov'а в ветке .net, ощущение того, что растет второй c++, укрепляется в моем мозгу. мне становится отчетливо понятно, что чтобы узнать этот язык хорошо и использовать его полноценно, мне нужно потратить еще кучу времени. c# 1.1 был довольно прост, чтобы не заглядывать в lang spec. не подумайте, что я собираюсь поднять панику, просто интересно, что кто думает по этому поводу.
Этюды nikov'a — это все же очень глубококопание — 90% разработчиков не знает ответов на большинство из них и живет себе припеваючи. В спек заглядывать не обязательно — программировать вполне можно прочитав например Троелсена (так сказать спек в разжеванном виде).
Ну если считать хорошими языки по длине спецификации — то конечно данный язык полный отстой. Но я бы определил правильный язык для mainstream — это насколько удобно пользоваться языком не заглядывая ни в спецификации, ни в хелпари, ни в google. И тут все таки С# на порядок более удобоваримый язык. В подавляющем большинстве случаев его поведение интуитивно понятно. Во многих случаях помогает сам компилятор выводя корректную информацию об ошибках. Так что, для чего он создавался, для того он и работает на ура. Правда это не всегда касается прилагаемых к нему библиотек.
Здравствуйте, GlebZ, Вы писали:
GZ>Являются частью стандарта. Но вопрос в следующем. Когда мы выполняем delete * from students s where (select min(mark) from exam where exam.studentID = s.id) < 3 мы попадаем в классические грабли ORM.
Ничего подобного. Если мы не пытаемся действовать в рамках безнадежно прогнившей концепции FBORM, то всё в порядке. GZ>Мы положили на валидацию. Мы не можем сказать какой объект student был уже удален.
Почему? Можем. У нас удалены все объекты, у которых минимальная оценка меньше тройки. GZ>И мы не можем сказать ваще какие объекты удалены и насколько у нас актуальные данные в памяти поскольку есть триггеры и каскадные удаления.
Совершенно верно. Актуальность данных в памяти — зловредная штука, полагаться на нее нельзя. Программисты на plain old SQL и Lightweight ORM об этом подсознательно помнят всегда: данные — одноразовая штука, а не магически обновляемый образ своего прототипа.
А вот пользователи FBORM пытаются полагаться на состояние кэша, что крайне противопоказано по медицинским соображениям.
GZ>По факту классическая рассинхронизация оперативной памяти и состояния на БД. Подобный запрос только увеличит глубину падения в наших глубинах.
Поэтому нужно восстать из зада и перестать слепо полагаться на кэш вообще. Идеология, где каждый объект для убийства нужно тащить целиком в память (как, впрочем, и для изменения) — глубоко порочна по своей природе.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Mirrorer, Вы писали:
M>Ну например. Возьмем простой пример. Просуммировать список чисел M>
M>var sum = 0;
M>foreach var x in someList
M> sum += x
M>
M>Допустим нам понадобилось сделать умножение. M>И что видно ? Видно дублирование кода. Отличие только в начальном значении суммы и функции, которая будет применяться на каждом шаге.
M>
M> var sum2 = Accumulate<int, int>(0, (s, x) => s + x);
M>
M>Мы теперь можно чувствовать себя крутым. Мы абсрагировали способ обхода коллекции (foreach) от операций которые будут выполняться на каждом шаге. M>Уберутся ненужные дублирования и т.п.
А в чем заключается убирание дублирования? При императивном подходе мы дважды писали foreach, при функциональном дважды пишем Accumulate. В чем выигрыш?
При этом выучив foreach один раз его можно использовать в миллионе случаев, а Accumulate покрывает куда меньшее количество случаев, соответственно для того, чтобы иметь возможность решить те же задачи, которые решаются с помощью foreach, нужно выучить не только Accumulate, но и еще 125 различных функций.
Из сказанного не следует, что я являюсь противником функционального подхода. Напротив, я считаю, что костяк приложения должны составлять статические функции, а объекты, как правило, быть лишь обертками над ними. Но как раз с точки зрения алгоритмики область применения функционального подхода достаточно узка (хотя и безусловно существует). Сложные алгоритмы записанные в императивном стиле, как правило, проще и в понимании и в отладке, т.к. при императивном подходе есть возможность опуститься на уровень одного элемента, т.е. части результата, а при функциональном подходе приходиться сразу мыслить на уровне коллекций, т.е. результата в целом.
По-своему опыту скажу, что в случае простых преобразований вместо трех строчек с foreach'ем я охотно использую статистическую функцию в тех случаях, когда этой функции не нужно принимать делегат, например: _.Combine<T>(params IEnumerable<T>[] collections). Если функция использует делегат, то чуть большая лаконичность написания, на мой взгляд, не окупает необходимости вспоминать специальную функцию.
Функции же с делегатами я охотно использую только в случае достаточно сложных, но стандартных преобразований, например:
Вот в решении подобных стандартных задач функциональному подходу самое место.
ps
Т.е. ни в коем случае нельзя противопоставлять императивный и функциональный подход, подавая функциональщину как серебрянную пулю, которая в скором времени вытеснит императивщину. Главное достоинство C# заключается в том, что он позволяет использовать и тот, и другой подход, выбирая более подходящий для конкретной задачи.
Здравствуйте, Константин Л., Вы писали:
КЛ>Здравствуйте, Lloyd, Вы писали:
КЛ>[]
КЛ>что в линке под айдентити подразумевается
подразумевается, что объект с заданным ключом будет существовать в пределах DataContext-а в единственном экземпляре, вне звисимости от того, через какое кол-во запросов он выл возвращен.
from c in context.Customers select c будет содержать from c in context.Customers where c.ID = 1 select c
Здравствуйте, Огнеплюх, Вы писали:
N>>* что метод помеченный unsafe можно взывать только тоже из unsafe метода. О>Может имелось ввиду наоборот ? Что например функции kernel.dll ( unsafe ) можно вызывать только из метода помеченным unsafe ?
Тоже неверно. Чтобы использовать P/Invoke не обязательно объявлять метод unsafe.
N>>* что из статического метода нельзя вызвать экземпляный О>Дык это вроде верно
Тогда экземплярные методы вообще никогда бы не вызывались, так как программа начинает выполнение со статического метода Main.
N>>* при попытке обратиться из финализатора к другому объекту, того объекта уже может не существовать в памяти О>Естествено, не факт что объект еще жив и не попал в мусороуборочную машину.
Вот я и говорю, что у Троелсена представления на уровне таких предрассудков.
Если код смог получить ссылку на объект, значит объект еще в памяти.
3.9 Automatic memory management
....
if that object, or any part of it, cannot be accessed by any possible continuation of execution, including the running of destructors, the object is considered inaccessible and the object becomes eligible for collection.
Здравствуйте, MxKazan, Вы писали:
MK>Согласен с p.s. ...реальным плюсом со времен C# 1.1 явились только generic'и...меня огорчают extension methods...Подстановка типов для generic'ов...Кому оно необходимо?..А еще я бы убил yield return...
Я не понял — это такой тонкий стеб?
Если нет, то я знаю отличный C# который тебе подойдет — Java. Отличный такой каменный топор с поддержкой ООП. Как раз для тех кто боится машин и оборудования.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, MxKazan, Вы писали:
MK>Так вот не торопятся переходить на .Net 3, именно потому что не видят от этого плюсов. С первого на второй перескочили практически сразу. Для меня это показатель.
Это показатель того, что со временем люди становятся всё более и более консервативными и всё больше и больше боятся расстаться со своим хламом.
Неясность изложения обычно происходит от путаницы в мыслях.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, MxKazan, Вы писали:
MK>Что могут предложить нововведения C# 3.0?
Я не знаю какие задачи они решают, поэтому без понятия что им может предложить C#.
Мне C# 3.0 дал следующее:
1. Типизацию работы с данными БД.
2. linq 2 objects принципиально изменил способы обработки данных в памяти.
3. Возможность работать в функциональном стиле с человеческим лицом.
Неясность изложения обычно происходит от путаницы в мыслях.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, MxKazan, Вы писали:
MK>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, MxKazan, Вы писали:
IT>>>>1. Типизацию работы с данными БД. MK>>>Ну в этом Linq далеко не первый. При этом в нём и гемора хватает, см. про удаление
. Мне также, например, не понравилось отсутствие того, что в ADO Entity Framework называют концептуальным слоем. Насколько я понимаю, Linq-to-Sql настраивается на модель БД при помощи атрибутов, следовательно, например, при изменении имени поля, мне приходится заниматься перегенерацией классов и перекопиляцией. Я уже и молчу про то, что куча настроек теряется при перегенерации (например, касательно участия поля в update'ах) G>>Вы просто не умеете его готовить. Я юзаю Linq с самого релиза, проблем не возникало. MK>Не-не-не, так дело не пойдёт. Есть конкретная задача, я её привел в теме, куда ведет ссылка. Прошу, выдайте мне решение. Я хочу удалить объекты из базы, просто по какому-то критерию.
Не получится никак. Вернее совсем никак. Это противречит реализации Linq2SQL. Я готов мириться с такой вселенской несправедливостью, учитывая кучу других полезностей.
Если вам нужны все возможности SQL, то используйте SQL, а не Linq.
Здравствуйте, MxKazan, Вы писали:
G>>ЗЫ. Я подобное мнение видел у прожженых C++ников, которые впоследствие перешли на C#. MK>Можно расслабиться и спокойно общаться. Мой профессиональный опыт — 3 года сплошного C#. Никакого C++.
Вот и выросло новое поколение
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, gandjustas, Вы писали: G>>А можно ли использовать все возможности запросов в операторе delete? S>Да. Всю мощь SQL.
Да уж, надо изучать T-SQL.
G>>Может оказаться что на уровне генерации sql по Expression такая проблема не решается вообще. S>Очевидно, решается. Если можно сделать select, то можно и delete. S>Аналогичная задача возникает у нас и при попытке воспользоваться insert into ... select ().
А еще update есть...
Здравствуйте, VladD2, Вы писали:
VD>>>Откровенно говоря, товарищь прав в том, что дизайнер и кодогенераторы (а по мне так и весь подход) студии кривоваты. Но надо все же понимать разницу между самим LINQ и визуальными средствами его поддержки.
L>>Только не надо про nemerle
VD>Причем тут Немерле? Ты давно в отпуске то был?
Переходить на личности тоже не надо.
P.S. В отпуске был в июле.
Здравствуйте, MxKazan, Вы писали:
MK>Мы все-время рассуждаем в рамках того насколько это легко Linq'у. MK>Словно не он для меня создан, а я для него
Он создан не для тебя, а для широких слоев населения. Linq for SQL — это концепция. Если бы это был чистый зайа, как говорил Антон, то такие массовые операции вполне подошли бы. Однако он берет на себя еще функцию обеспечения транзакции с помощью identity tracking, и это несколько более мощная концепция чем простой SQLBuilder.(ты ведь уже заметил несовместимость c identity tracking) И обеспечивает потребности более широких слоев населения. Если же сделать мусорку плохо совместимых концепций, то ничего хорошего не получится. Таких примеров — море.
Как и у любого универсального продукта, линка обладает недостатком. Если выходишь за границы концепции, то это потребует некоторых усилий. Так всегда было, и так всегда будет. Большинство путей обходов уже продуманы создателями и предоставлены интерфейсы. Так что по качеству универсализма, IMHO Linq for SQL продукт высшей пробы.
Здравствуйте, GlebZ, Вы писали: GZ>Я совершенно против чтобы из зайца делали бегемота с непонятной мне целью. Ты кстати назвал очень интересное преимущество называемое "рефакторинг". А это означает что сам запрос может быть размазан по коду и инкапсулирован в функции которые не показывают как именно делается запрос. И это налагает обязательства. GZ>Селективные запросы вполне совместимы с такой идеалогией, поскольку мы вполне можем с помощью Identity гарантировать житие транзакции. А вот ежели мы впендюриваемся в запросы без Identity — мы усложняем не только само Linq, но и себе жизнь. Притом на порядок. От этого больше вреда чем пользы.
Поток сознания не понял.
GZ>Цезарю — цезарево, авгию — авгиево. Для массированной обработки данных есть процедуры. GZ>Не вмещаешься в предложенную концепцию — выходи за пределы.
По прежнему продолжаю непонимать, почему граница рисуется между select и всеми остальными. Мне что, сложные селекты тоже писать "на процедурах"?
На всякий случай напомню, что могучесть линка в частности в том, что обеспечивается эффект динамического построения запросов при соблюдении статического контроля корректности. Типа
var q = from ... where ... select ...
if (somecondition)
{
q = from q where AdditionalPredicate select ...
}
И эта техника равно применима ко всем типам запросов. Почему я не могу сначала построить нетривиальный select, а затем скормить его на вход insert'у не вытаскивая данные из SQL сервера?
GZ>Только вводить такие запросы — это гадить на саму концепцию.
Не надо вот этих вот копротерминов. Если ваше понимание концепции не совпадает с моим, то не нужно думать, что мое чем-то хуже.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
RO>Во-первых, не издевайтесь над Трёльсеном (не знаю, хорошо ли он пишет, но всё равно нечего перевирать имя).
Расслабься, после Бьёрна Страустрапа нам уже ничего не страшно.
RO>Во-вторых, все известные мне языки, которые пытались устранить низкоуровневые «сложности» и объединить сущности «объект» и «адрес объекта», наступили на одни и те же грабли и связывают объекты вместо копирования или наоборот неочевидным для программиста образом. Чем больше будет распространен C#, тем больше анонимов будут задавать одни и те же вопросы на соответствующих форумах. Да что далеко ходить: самое верхнее сообщение на rsdn.dotnet под модным номером 3110110
: «А теперь вопрос — почему при удалении строк из dt также удаляются строки из ViewState? Догадываюсь, что копируется ссылка, а как правильно скопировать, чтобы создалась копия объекта?». Тем более, что грабли замедленного действия: программа компилируется и работает, но тихо редактирует не те данные.
Ага, а C++-ное копирование никаких граблей не подбрасывает, и анонимы всегда редактируют именно те данные, которые надо. Ага. Интересно, а анонимов не смущает, что когда они редактируют вьюху SELECT * FROM tbl1 WHERE col1=0, при этом предательским образом изменяются данные в tbl1?
RO>В-третьих, пока C# привязан к одной определенной платформе, он годится только на то, чтобы флудить о нем в ФП, а на сервер пойдут решения, которые при нужде можно будет перенести куда понадобится
Гм, речь идёт о каком-то одном сервере или о серверах вообще?
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Sinclair, Вы писали:
L>>>А поэтому и нет необходимости delete по expression-у в DataContext-е. S>> Логика на высоте. "Новая помада не подошла к цвету машины, поэтому я пошла пешком".
S>>Я всё еще не вижу причин, по которой ты считаешь identity tracking заметно лучше, чем прямое отображение insert/update/delete в SQL.
L>я так не считаю, я считаю что DataContext (c identity tracking) лучше чем DataContext(Sinclair edition) (c identity tracking и delete-ами через expression в обном флаконе). L>Так надеюсь понятнее?
Lloyd, по-моему, Sinclair имеет ввиду, что ему не нужно identity tracking, если оно мешает выполнять типовые запросы БД. Получилась концепция частично ради самой себя — пользоваться можно, но то здесь, то там приходиться извращаться для решения типовых задач.
Здравствуйте, MxKazan, Вы писали:
MK>Только всё же выскажу, что эти var'ы прямо глаза коробят, того и гляди о типизации думать перестанем
В пределах метода оно не страшно. Особенно если методы не на 10 экранов. Все понятно из контекста.
Тем более что типизация никуда не девается. В Haskell-e допустим можно вообще ни один тип не указывать, все компилятор выведет. Но от этого язык менее строгим не становится.
MK>P.S. Гы. И здесь это любимое на всяких музыкальных тру-форумах слово "мейнстрим"
Ну а как иначе. Большинство идей, которые попадают в языки, были описаны в академических исследованиях 19.. лохматого года. А потом по чуть-чуть из башен слоновой кости идеи перетекают в индустрию в пережеванном и удобном для употребления виде.
Х>Этюды nikov'a — это все же очень глубококопание — 90% разработчиков не знает ответов на большинство из них и живет себе припеваючи. В спек заглядывать не обязательно — программировать вполне можно прочитав например Троелсена (так сказать спек в разжеванном виде).
Но я не утверждаю что читать спек не надо, другое дело, что не обязательно.
Здравствуйте, Хэлкар, Вы писали:
Х>В спек заглядывать не обязательно — программировать вполне можно прочитав например Троелсена (так сказать спек в разжеванном виде).
Вот только не Троелсена. То что он пишет о C#, имеет очень мало общего с реальностью. Рихтер неплохо пишет.
Здравствуйте, nikov, Вы писали:
Х>>В спек заглядывать не обязательно — программировать вполне можно прочитав например Троелсена (так сказать спек в разжеванном виде). N>Вот только не Троелсена. То что он пишет о C#, имеет очень мало общего с реальностью. Рихтер неплохо пишет.
А что вам не нравится у Троелсена? Я не говорю что книга идеальная, но в целом нормальная книга на мой взгляд. Можно немного подробнее?
Здравствуйте, MozgC, Вы писали:
MC>А что вам не нравится у Троелсена? Я не говорю что книга идеальная, но в целом нормальная книга на мой взгляд. Можно немного подробнее?
К сожалению книги под рукой нет. Но помню, что находил там много просто неверных утверждений.
Единственное, что помню наизусть — он писал:
* что метод помеченный unsafe можно взывать только тоже из unsafe метода.
* что из статического метода нельзя вызвать экземпляный
* при попытке обратиться из финализатора к другому объекту, того объекта уже может не существовать в памяти
Здравствуйте, Хэлкар, Вы писали:
Х>Здравствуйте, Константин Л., Вы писали:
КЛ>>Как вам язычок? Х>Супер КЛ>> Возможности? Х>Супер КЛ>>Lazy eval.? Closures? Правила explicit/implicit conv. (особенно для типов-параметров generics)? Х>А что раньше не было разве? Начиная со второго C# все это было.
было, но очевиден ли этот код?
delegate int d();
d func = null;
foreach(int a in new int[]{1, 2, 3})
func = delegate { return a; }
d();
КЛ>>А learning curve? Размер стандарта? Х>
угу
КЛ>>пс: каждый день, когда наталкиваюсь на этюды nikov'а в ветке .net, ощущение того, что растет второй c++, укрепляется в моем мозгу. мне становится отчетливо понятно, что чтобы узнать этот язык хорошо и использовать его полноценно, мне нужно потратить еще кучу времени. c# 1.1 был довольно прост, чтобы не заглядывать в lang spec. не подумайте, что я собираюсь поднять панику, просто интересно, что кто думает по этому поводу.
Х>Этюды nikov'a — это все же очень глубококопание — 90% разработчиков не знает ответов на большинство из них и живет себе припеваючи. В спек заглядывать не обязательно — программировать вполне можно прочитав например Троелсена (так сказать спек в разжеванном виде).
у меня почему-то совсем другое впечатление. может быть потому что я привык к с++...
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Константин Л., Вы писали:
GZ>Ну если считать хорошими языки по длине спецификации — то конечно данный язык полный отстой. Но я бы определил правильный язык для mainstream — это насколько удобно пользоваться языком не заглядывая ни в спецификации, ни в хелпари, ни в google. И тут все таки С# на порядок более удобоваримый язык. В подавляющем большинстве случаев его поведение интуитивно понятно. Во многих случаях помогает сам компилятор выводя корректную информацию об ошибках. Так что, для чего он создавался, для того он и работает на ура. Правда это не всегда касается прилагаемых к нему библиотек.
удобоваримее с++ да. но, похоже, это только у меня, но я пока не смогу ответить на 90% этюдов nikov'а буду считать что язык знаю плохо.
мне понадобилась куча времени, чтобы хорошо выучить с++. теперь надо чуть меньше, чтобы так же выучить c#. по-моему, это не есть хорошо.
Здравствуйте, nikov, Вы писали:
N>Здравствуйте, Константин Л., Вы писали:
КЛ>>Размер стандарта?
N>Я бы обратил внимание в первую очередь не на его размер, а на то, что он написан очень доходчиво и хорошо структурирован.
насколько хватило времени понять, он гораздо проще стандарта с++ (уж простите что всюду приплетаю), но 500 с гаком страниц это слишком
Здравствуйте, Константин Л., Вы писали:
КЛ>удобоваримее с++ да. но, похоже, это только у меня, но я пока не смогу ответить на 90% этюдов nikov'а буду считать что язык знаю плохо.
Тем не менее на практике такое не встречается, а если и встречается, то обычно легко понять в чем дело, когда тебе не гадать надо, а просто посмотреть, как поведет себя компилятор. Дургими словами, имея ответ, гораздо проще восстановить причину.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111 on Windows Vista 6.0.6001.65536>>
Здравствуйте, nikov, Вы писали:
N>Здравствуйте, MozgC, Вы писали:
MC>>А что вам не нравится у Троелсена? Я не говорю что книга идеальная, но в целом нормальная книга на мой взгляд. Можно немного подробнее?
N>К сожалению книги под рукой нет. Но помню, что находил там много просто неверных утверждений. N>Единственное, что помню наизусть — он писал: N>* что метод помеченный unsafe можно взывать только тоже из unsafe метода.
Может имелось ввиду наоборот ? Что например функции kernel.dll ( unsafe ) можно вызывать только из метода помеченным unsafe ?
N>* что из статического метода нельзя вызвать экземпляный
Дык это вроде верно
class A
{
public static void StatMethod()
{
Method (); //// И что спрашивается мы вызовем если в коде напишем A.StatMethod() ? Конечно нельзя экземплярные методы в статических дергать.
}
public void Method()
{
}
}
N>* при попытке обратиться из финализатора к другому объекту, того объекта уже может не существовать в памяти
Естествено, не факт что объект еще жив и не попал в мусороуборочную машину.
Здравствуйте, Константин Л., Вы писали:
КЛ>Как вам язычок? Возможности? Lazy eval.? Closures? Правила explicit/implicit conv. (особенно для типов-параметров generics)? А learning curve? Размер стандарта?
Вполне себе язык, разве что мне лично очень не хватает паттерн-матчинга и алгебраических типов данных.
КЛ>пс: каждый день, когда наталкиваюсь на этюды nikov'а в ветке .net, ощущение того, что растет второй c++, укрепляется в моем мозгу. мне становится отчетливо понятно, что чтобы узнать этот язык хорошо и использовать его полноценно, мне нужно потратить еще кучу времени. c# 1.1 был довольно прост, чтобы не заглядывать в lang spec. не подумайте, что я собираюсь поднять панику, просто интересно, что кто думает по этому поводу.
Я кажется Вас понимаю, тут нужно изучать не в глубину, а в ширину. Много различных концепций объединены в 3й шарп, в основном от мира ФП. Надо лишь немного расширить кругозор, изучить какой-либо простенький ФП язык, а когда поймете суть этих концепций, все встанет на свои места.
Lisp is not dead. It’s just the URL that has changed: http://clojure.org
КЛ>delegate int d();
КЛ>d func = null;
КЛ>foreach(int a in new int[]{1, 2, 3})
КЛ> func = delegate { return a; }
КЛ>d();
КЛ>
Извините, но то что на С++ концепция замыканий работает по другому еще не повод ругать концепцию C#.
КЛ>>>А learning curve? Размер стандарта? Х>>
КЛ>угу
Стандарт С++ имхо ничуть не проще. А сколько людей на нем пишет!
КЛ>у меня почему-то совсем другое впечатление. может быть потому что я привык к с++...
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Хэлкар, Вы писали:
Х>>Извините, но то что на С++ концепция замыканий работает по другому еще не повод ругать концепцию C#.
L>В C++ нет замыканий.
Здравствуйте, yumi, Вы писали:
Y>Здравствуйте, Константин Л., Вы писали:
КЛ>>Как вам язычок? Возможности? Lazy eval.? Closures? Правила explicit/implicit conv. (особенно для типов-параметров generics)? А learning curve? Размер стандарта?
Y>Вполне себе язык, разве что мне лично очень не хватает паттерн-матчинга и алгебраических типов данных.
КЛ>>пс: каждый день, когда наталкиваюсь на этюды nikov'а в ветке .net, ощущение того, что растет второй c++, укрепляется в моем мозгу. мне становится отчетливо понятно, что чтобы узнать этот язык хорошо и использовать его полноценно, мне нужно потратить еще кучу времени. c# 1.1 был довольно прост, чтобы не заглядывать в lang spec. не подумайте, что я собираюсь поднять панику, просто интересно, что кто думает по этому поводу.
Y>Я кажется Вас понимаю, тут нужно изучать не в глубину, а в ширину. Много различных концепций объединены в 3й шарп, в основном от мира ФП. Надо лишь немного расширить кругозор, изучить какой-либо простенький ФП язык, а когда поймете суть этих концепций, все встанет на свои места.
да нет, с lisp я знакомился 3м курсе института, и идеи фп для меня не новы и не чужды. я именно про глубину
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Хэлкар, Вы писали:
L>>>В C++ нет замыканий.
Х>>ОК, неправильно сказал — имел в виду лямбды/делегаты.
L>лямбд там тоже нет.
Блин, я не конкретно лямбды имею в виду. Я имею в виду реализацию замыканий в лямбдах/делегатах C#!
Здравствуйте, Константин Л., Вы писали:
КЛ>удобоваримее с++ да. но, похоже, это только у меня, но я пока не смогу ответить на 90% этюдов nikov'а буду считать что язык знаю плохо.
Ну, если так подходить, то ты и русский язык знаешь плохо. Словарный запас человека ограничен. Количество применяемых слов — на порядок меньше. Значения некоторых слов понимаются из контекста. Однако это не мешает людям общаться. Язык понимается на уровне интуиции. Вот так и С# более интуитивно понятен чем С++. Главное знать идеомы языка, а смысл понятен из контекста. И конечно упомянутая статическая компиляция. Не нужно знать правила приведения типов. Это вполне понимает компилятор. Он вполне хорошо шарит в спецификации. Этого вполне достаточно, чтобы в большинстве случаев, он дал тебе понять что где и как. И этого вполне достаточно чтобы плодотворно работать на благо себя и родины.
Для того чтобы вызубрить спецификации, нужно быть любителем спецификаций. Для того чтобы работать на этом языке, нужно быть просто умным человеком. Иначе придется признать что мы и на русском не можем разговаривать.
КЛ>мне понадобилась куча времени, чтобы хорошо выучить с++.
Везука. А вот мне все равно он преподносит сюрпризы.
N>3.9 Automatic memory management
N>....
N>if that object, or any part of it, cannot be accessed by any possible continuation of execution, including the running of destructors, the object is considered inaccessible and the object becomes eligible for collection.
Допустим, были объекты A и B, ссылающиеся друг на друга. На объект A была ссылка в Main. Затем эту ссылку занулили. Объекты A и B должны быть подобранны сборщиком мусора и для них должны быть вызваны финализаторы. Получается, что .NET гарантирует, что сначала будут вызваны финализаторы для A и B, и только после этого они будут уничтожены полностью?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
N>>3.9 Automatic memory management
N>>....
N>>if that object, or any part of it, cannot be accessed by any possible continuation of execution, including the running of destructors, the object is considered inaccessible and the object becomes eligible for collection.
E>Допустим, были объекты A и B, ссылающиеся друг на друга. На объект A была ссылка в Main. Затем эту ссылку занулили. Объекты A и B должны быть подобранны сборщиком мусора и для них должны быть вызваны финализаторы. Получается, что .NET гарантирует, что сначала будут вызваны финализаторы для A и B, и только после этого они будут уничтожены полностью?
Гарантируется, что память, занятая объектом, не будет освобождена, пока к какой-то части объекта могут быть обращения из его финализатора или любого другого финализатора.
Здравствуйте, nikov, Вы писали:
E>>Допустим, были объекты A и B, ссылающиеся друг на друга. На объект A была ссылка в Main. Затем эту ссылку занулили. Объекты A и B должны быть подобранны сборщиком мусора и для них должны быть вызваны финализаторы. Получается, что .NET гарантирует, что сначала будут вызваны финализаторы для A и B, и только после этого они будут уничтожены полностью?
N>Гарантируется, что память, занятая объектом, не будет освобождена, пока к какой-то части объекта могут быть обращения из его финализатора или любого другого финализатора.
Так за счет чего это гарантируется:
1. Финализаторы вызываются до освобождения памяти?
2. Объекты A и B вообще не попадают под сборку мусора?
3. Что-то еще?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
N>>Гарантируется, что память, занятая объектом, не будет освобождена, пока к какой-то части объекта могут быть обращения из его финализатора или любого другого финализатора.
E>Так за счет чего это гарантируется:
Стандарт не предписывает конкретного механима, но на практике, при создании объекта (точнее перед вызовом пользовательского кода констуктора, и даже перед вызовом статического конструктора, если его надо вызвать) имеющего тип, переопределяющий финализатор, ссылка на этот объект помещается в специальную очередь, которая сборщиком мусора считается корнем.
Здравствуйте, nikov, Вы писали:
N>Стандарт не предписывает конкретного механима, но на практике, при создании объекта (точнее перед вызовом пользовательского кода констуктора, и даже перед вызовом статического конструктора, если его надо вызвать) имеющего тип, переопределяющий финализатор, ссылка на этот объект помещается в специальную очередь, которая сборщиком мусора считается корнем.
Пока из ваших объяснений я так и не понял, чтоже именно произойдет с объектами A и B. Такое впечатление, что они либо остануться жить вечно, либо их финализаторы гарантированно вызовутся раньше очистки памяти.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Пока из ваших объяснений я так и не понял, чтоже именно произойдет с объектами A и B. Такое впечатление, что они либо остануться жить вечно, либо их финализаторы гарантированно вызовутся раньше очистки памяти.
Почитайте Рихтера CLR via C#, Вам все станет понятно.
Здравствуйте, eao197, Вы писали:
E>Пока из ваших объяснений я так и не понял, чтоже именно произойдет с объектами A и B. Такое впечатление, что они либо остануться жить вечно, либо их финализаторы гарантированно вызовутся раньше очистки памяти.
Здравствуйте, IT, Вы писали:
IT>Ничего так. Linq очень хорош. И как обманка для генерации SQL, и как молотилка данных в памяти. Но в целом развиваться ещё есть куда.
Становиться ещё более функциональным?
Здравствуйте, EvilChild, Вы писали:
IT>>Ничего так. Linq очень хорош. И как обманка для генерации SQL, и как молотилка данных в памяти. Но в целом развиваться ещё есть куда. EC>Становиться ещё более функциональным?
В том числе.
Неясность изложения обычно происходит от путаницы в мыслях.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, maggot, Вы писали:
EC>>Он же существенно проще в освоении, чем C++. M>Интересное мнение. Хотя с C# я не работал, читая осуждения на форумах, у меня складывалось впечатление, что он сложнее С++. По крайней мере, там больше различных фитч. И не удивительно. Ведь у C# в отличие от C++ нет коммитета стандартизации — его разрабатывают в пределах одной компании, а следовательно изменения в язык могут вноситься быстрее.
Стандарт есть.
В нём меньше граблей разложено. Гораздо сложнее случайно прострелить себе ногу.
Почти всё реализовано интуитивно понятно.
В плюсах один name lookup чего стоит. Шаблоны тоже сложнее в использовании чем дженерики.
На дженериках compile time metaprogramming не замутишь.
Нет макросов.
Есть компонентность.
Это первое, что на ум приходит, если подумать, то найдётся ещё много чего.
Любой вменяемый плюсовик может продуктивно использовать C# с минимальными услиями — обратное неверно.
M>Да, и чем, кстати, С++ сложен? ИМХО там всё довольно просто.
Сколько времени ты на нём пишешь?
Здравствуйте, EvilChild, Вы писали:
EC>Стандарт есть. EC>В нём меньше граблей разложено. Гораздо сложнее случайно прострелить себе ногу. EC>Почти всё реализовано интуитивно понятно. EC>В плюсах один name lookup чего стоит.
Конечно, можно написать код, в котором потом разбираться будет очень проблематично. EC>Шаблоны тоже сложнее в использовании чем дженерики. EC>На дженериках compile time metaprogramming не замутишь.
В этом их сила Кстати, в C# есть частичная специализация дженериков? EC>Нет макросов.
Макросы рудиментарный анахронизм. Я думаю, пора бы с новым стандартом избавить С++ от макросов. А для совместимости со старыми стандартами производители компиляторов могут делать дополнительные опции, включающие совместимость с ними.
А так, макросы не усложняют сам язык. Просто некоторые разработчики их лепят там, где без них можно обойтись. EC>Есть компонентность. EC>Это первое, что на ум приходит, если подумать, то найдётся ещё много чего. EC>Любой вменяемый плюсовик может продуктивно использовать C# с минимальными услиями — обратное неверно.
Ну а yield и всё что с ним связано считается простой вещью в C#?
EC>Сколько времени ты на нём пишешь?
3 года.
Здравствуйте, Klapaucius, Вы писали:
E>>Пока из ваших объяснений я так и не понял, чтоже именно произойдет с объектами A и B. Такое впечатление, что они либо остануться жить вечно, либо их финализаторы гарантированно вызовутся раньше очистки памяти.
K>Думаю, что это объясняется здесь.
Ну да, так и получается: f-reachable queue является одним из корней для GC, а изъятие объекта из f-reachable queue производится только после вызова финализатора. Т.е. пока оба финализатора для A и B не будут вызваны, ни один из них не попадет под очистку (т.к. кто-то из них остается в f-reachable queue). Следовательно, финализаторы гарантированно вызовутся раньше очистки памяти.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>>>Пока из ваших объяснений я так и не понял, чтоже именно произойдет с объектами A и B. Такое впечатление, что они либо остануться жить вечно, либо их финализаторы гарантированно вызовутся раньше очистки памяти.
E>Ну да, так и получается: f-reachable queue является одним из корней для GC, а изъятие объекта из f-reachable queue производится только после вызова финализатора. Т.е. пока оба финализатора для A и B не будут вызваны, ни один из них не попадет под очистку (т.к. кто-то из них остается в f-reachable queue). Следовательно, финализаторы гарантированно вызовутся раньше очистки памяти.
Если вызовутся, то вызовутся раньше очистки памяти. Вызов финализаторов, насколько я знаю, не гарантирован. Гарантирована жизнь объектов, к которым можно обратиться.
... << RSDN@Home 1.2.0 alpha 4 rev. 1110>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, maggot, Вы писали:
EC>>В плюсах один name lookup чего стоит. M>Конечно, можно написать код, в котором потом разбираться будет очень проблематично.
Не о том речь. Почитай правила поиска имен стандарт писали садомазохисты.
EC>>Шаблоны тоже сложнее в использовании чем дженерики. EC>>На дженериках compile time metaprogramming не замутишь. M>В этом их сила
Посмотри на немерле... тогда ты может быть поймешь что такое метапрограммирование.
M>Кстати, в C# есть частичная специализация дженериков?
Нет и не надо.
M>А так, макросы не усложняют сам язык. Просто некоторые разработчики их лепят там, где без них можно обойтись.
Есть много мест где без хотябы текстовых макросов не обойтись (в смысле иначе геморой страшный).
M>Ну а yield и всё что с ним связано считается простой вещью в C#?
Тривиальной.
Я кстати к С++ его прикрутил. Макросами... ну влом мне было руками конечный автомат для парсинга HTTP протокола в асинхронном сервере писать.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, maggot, Вы писали:
EC>>>В плюсах один name lookup чего стоит. M>>Конечно, можно написать код, в котором потом разбираться будет очень проблематично. WH>Не о том речь. Почитай правила поиска имен стандарт писали садомазохисты.
ничего особенного
EC>>>Шаблоны тоже сложнее в использовании чем дженерики. EC>>>На дженериках compile time metaprogramming не замутишь. M>>В этом их сила WH>Посмотри на немерле... тогда ты может быть поймешь что такое метапрограммирование.
+1
M>>Кстати, в C# есть частичная специализация дженериков? WH>Нет и не надо.
Здравствуйте, Константин Л., Вы писали:
WH>>Не о том речь. Почитай правила поиска имен стандарт писали садомазохисты. КЛ>ничего особенного
Это ADL то ничего особенного?
M>>>Кстати, в C# есть частичная специализация дженериков? WH>>Нет и не надо. КЛ>-1
Специализация вобще и частичная в частности очень дорого стоят. Они несовместимы с компонентной моделью.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Константин Л., Вы писали:
WH>>>Не о том речь. Почитай правила поиска имен стандарт писали садомазохисты. КЛ>>ничего особенного WH>Это ADL то ничего особенного?
ага
M>>>>Кстати, в C# есть частичная специализация дженериков? WH>>>Нет и не надо. КЛ>>-1 WH>Специализация вобще и частичная в частности очень дорого стоят. Они несовместимы с компонентной моделью.
не совместима и не надо разные вещи. да и наверняка что-нить можно было придумать, хоть и не тривиально это все
Здравствуйте, Константин Л., Вы писали:
КЛ>не совместима и не надо разные вещи.
На халяву почему бы и нет. Но если нужно платить...
КЛ>да и наверняка что-нить можно было придумать, хоть и не тривиально это все
Придумай.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, MxKazan, Вы писали:
MK>>Согласен с p.s. ...реальным плюсом со времен C# 1.1 явились только generic'и...меня огорчают extension methods...Подстановка типов для generic'ов...Кому оно необходимо?..А еще я бы убил yield return...
VD>Я не понял — это такой тонкий стеб?
VD>Если нет, то я знаю отличный C# который тебе подойдет — Java. Отличный такой каменный топор с поддержкой ООП. Как раз для тех кто боится машин и оборудования.
Причем здесь Java? Меня спросили про C# 3.0, я высказал своё мнение. На мой взгляд, в языке появляется всё больше и больше способов, как любят говорить некоторые, "выстрелить себе в ногу". Я не боюсь ни машин, ни оборудования и часто на ура воспринимаю разные нововведения. Но вот я чувствую, что скоро только и придется заниматься отучением "молодых" где ни попадя впихивать extension methods, юзать без понимания смысла yield return, попутно занимаясь разгадыванием, какой же generic метод решил вызвать компилятор, из-за того, что позволил чуваку не вписывать тип-параметр. Знаю одну очень хорошую фирму, небольшую, но с очень высоким профессиональным уровнем. Они свой Framework для бизнес-приложений давно наваяли в том варианте, который теперь используются в dependency properties в WPF. Так вот не торопятся переходить на .Net 3, именно потому что не видят от этого плюсов. С первого на второй перескочили практически сразу. Для меня это показатель.
Здравствуйте, MxKazan, Вы писали:
MK>Так вот не торопятся переходить на .Net 3, именно потому что не видят от этого плюсов. С первого на второй перескочили практически сразу.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, MxKazan, Вы писали:
MK>>Так вот не торопятся переходить на .Net 3, именно потому что не видят от этого плюсов. С первого на второй перескочили практически сразу.
L>Неужели их даже линк не вдохновил?
Если рассматривать Linq как средство доступа к БД, то ими разработанный Фреймворк сам позволяет делать примерно то же самое — есть низкий уровень генерации SQL, а всё остальное — обычные .Net классы, умело вписанные в стандартные задачи бизнеса. Поэтому Linq им просто не нужен. Более того, как человек использовавший и то и другое, не могу однозначно сказать что лучше. Подозреваю, что другие сферы применения Linq не сильно представлены в их приложениях, чтобы ради этого переходить на новый FW.
По мне, Linq — хорошая вещь как идея, надо было упомянуть его вместе с generic'ами. Но реализация Linq-to-Sql огорчила, например, невозможностью сделать DELETE без предварительного SELECT'а. Возможно я просто не нашел как, времени тогда было немного, буду рад если кто поделится ссылками.
Здравствуйте, MxKazan, Вы писали:
MK>Если рассматривать Linq как средство доступа к БД, то ими разработанный Фреймворк сам позволяет делать примерно то же самое — есть низкий уровень генерации SQL, а всё остальное — обычные .Net классы, умело вписанные в стандартные задачи бизнеса. Поэтому Linq им просто не нужен. Более того, как человек использовавший и то и другое, не могу однозначно сказать что лучше. Подозреваю, что другие сферы применения Linq не сильно представлены в их приложениях, чтобы ради этого переходить на новый FW.
Нет, я имел в виду Linq to Objects
MK>По мне, Linq — хорошая вещь как идея, надо было упомянуть его вместе с generic'ами. Но реализация Linq-to-Sql огорчила, например, невозможностью сделать DELETE без предварительного SELECT'а. Возможно я просто не нашел как, времени тогда было немного, буду рад если кто поделится ссылками.
Не знаю, сработает ли, но можно пропробовать создать пустую сущность с выставленным ID, приаттачить ее к контексту, и потом удалить ее из контекста.
Здравствуйте, Lloyd, Вы писали:
L>Не знаю, сработает ли, но можно пропробовать создать пустую сущность с выставленным ID, приаттачить ее к контексту, и потом удалить ее из контекста.
Речь не об ID.
Речь об аналоге
delete * from students s where (select min(mark) from exam where exam.studentID = s.id) < 3
Заселектить таких студентов мы можем только в путь. А вот делитнуть — не вполне понятно как.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Lloyd, Вы писали:
L>>Не знаю, сработает ли, но можно пропробовать создать пустую сущность с выставленным ID, приаттачить ее к контексту, и потом удалить ее из контекста. S>Речь не об ID. S>Речь об аналоге
S>
S>delete * from students s where (select min(mark) from exam where exam.studentID = s.id) < 3
S>
S>Заселектить таких студентов мы можем только в путь. А вот делитнуть — не вполне понятно как.
Именно об этом речь. Сделать что-то вроде "DELETE FROM tblMyTable WHERE myTableField = myProvidedValue" Как? Просмотрел ряд форумов, где прямо так и писали, мол "не могёт так Linq-To-Sql" — вначале заселекти всё, что myTableField = myProvidedValue, а потом уже удаляй. Никак ведь не катит, а
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, MxKazan, Вы писали:
MK>>Так вот не торопятся переходить на .Net 3, именно потому что не видят от этого плюсов. С первого на второй перескочили практически сразу. Для меня это показатель.
IT>Это показатель того, что со временем люди становятся всё более и более консервативными и всё больше и больше боятся расстаться со своим хламом.
Возможно и так. Однако, как я уже писал в соседней ветке, попробовав оба подхода (их FW и Linq), сам не могу сказать что Linq прямо так уж круче. В любом случае, не назвал бы работников той фирмы консервативными. Скорее они реально стараются взешивать "а надо ли?". Возможно Linq просто не оказался столь мощным аргументом (и я понимаю почему, опять же, см. соседний тред), а остальное — extensions и пр.лабуда успешно получены путем создания собственной библиотеки контролов. Ну вот, например, прежде чем перейти на FW2, плюсы generic'ов выясняли различными тестами — реально ли быстрее. Да — быстрее, выше, сильнее. Что могут предложить нововведения C# 3.0?
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Lloyd, Вы писали:
L>>Не знаю, сработает ли, но можно пропробовать создать пустую сущность с выставленным ID, приаттачить ее к контексту, и потом удалить ее из контекста. S>Речь не об ID. S>Речь об аналоге
S>
S>delete * from students s where (select min(mark) from exam where exam.studentID = s.id) < 3
S>
S>Заселектить таких студентов мы можем только в путь. А вот делитнуть — не вполне понятно как.
Если такие запросы выполнять, то Identity Tracking совсем работать не будет.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, MxKazan, Вы писали:
MK>>Что могут предложить нововведения C# 3.0?
IT>Я не знаю какие задачи они решают, поэтому без понятия что им может предложить C#.
IT>Мне C# 3.0 дал следующее:
IT>1. Типизацию работы с данными БД.
Ну в этом Linq далеко не первый. При этом в нём и гемора хватает, см. про удаление
. Мне также, например, не понравилось отсутствие того, что в ADO Entity Framework называют концептуальным слоем. Насколько я понимаю, Linq-to-Sql настраивается на модель БД при помощи атрибутов, следовательно, например, при изменении имени поля, мне приходится заниматься перегенерацией классов и перекопиляцией. Я уже и молчу про то, что куча настроек теряется при перегенерации (например, касательно участия поля в update'ах)
IT>2. linq 2 objects принципиально изменил способы обработки данных в памяти.
Так. Я видимо не в теме. А что принципиального нового linq 2 objects внёс по части "способы обработки данных в памяти"?
IT>3. Возможность работать в функциональном стиле с человеческим лицом.
Честно говоря, никогда не страдал от отсутствия подобного в C#
Здравствуйте, MxKazan, Вы писали:
IT>>1. Типизацию работы с данными БД. MK>Ну в этом Linq далеко не первый. При этом в нём и гемора хватает, см. про удаление
. Мне также, например, не понравилось отсутствие того, что в ADO Entity Framework называют концептуальным слоем. Насколько я понимаю, Linq-to-Sql настраивается на модель БД при помощи атрибутов, следовательно, например, при изменении имени поля, мне приходится заниматься перегенерацией классов и перекопиляцией. Я уже и молчу про то, что куча настроек теряется при перегенерации (например, касательно участия поля в update'ах)
Вы просто не умеете его готовить. Я юзаю Linq с самого релиза, проблем не возникало.
IT>>2. linq 2 objects принципиально изменил способы обработки данных в памяти. MK>Так. Я видимо не в теме. А что принципиального нового linq 2 objects внёс по части "способы обработки данных в памяти"?
IT>>3. Возможность работать в функциональном стиле с человеческим лицом. MK>Честно говоря, никогда не страдал от отсутствия подобного в C#
Вы действительно не в тебе, были бы в теме — оценили бы преимущества.
ЗЫ. Я подобное мнение видел у прожженых C++ников, которые впоследствие перешли на C#.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, MxKazan, Вы писали:
IT>>>1. Типизацию работы с данными БД. MK>>Ну в этом Linq далеко не первый. При этом в нём и гемора хватает, см. про удаление
. Мне также, например, не понравилось отсутствие того, что в ADO Entity Framework называют концептуальным слоем. Насколько я понимаю, Linq-to-Sql настраивается на модель БД при помощи атрибутов, следовательно, например, при изменении имени поля, мне приходится заниматься перегенерацией классов и перекопиляцией. Я уже и молчу про то, что куча настроек теряется при перегенерации (например, касательно участия поля в update'ах) G>Вы просто не умеете его готовить. Я юзаю Linq с самого релиза, проблем не возникало.
Не-не-не, так дело не пойдёт. Есть конкретная задача, я её привел в теме, куда ведет ссылка. Прошу, выдайте мне решение. Я хочу удалить объекты из базы, просто по какому-то критерию.
IT>>>2. linq 2 objects принципиально изменил способы обработки данных в памяти. MK>>Так. Я видимо не в теме. А что принципиального нового linq 2 objects внёс по части "способы обработки данных в памяти"?
IT>>>3. Возможность работать в функциональном стиле с человеческим лицом. MK>>Честно говоря, никогда не страдал от отсутствия подобного в C#
G>Вы действительно не в тебе, были бы в теме — оценили бы преимущества.
Отмахнуться — это удобно. А ответить на вопрос?
G>ЗЫ. Я подобное мнение видел у прожженых C++ников, которые впоследствие перешли на C#.
Можно расслабиться и спокойно общаться. Мой профессиональный опыт — 3 года сплошного C#. Никакого C++.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, MxKazan, Вы писали:
MK>>Здравствуйте, gandjustas, Вы писали:
G>>>Здравствуйте, MxKazan, Вы писали:
IT>>>>>1. Типизацию работы с данными БД. MK>>>>Ну в этом Linq далеко не первый. При этом в нём и гемора хватает, см. про удаление
. Мне также, например, не понравилось отсутствие того, что в ADO Entity Framework называют концептуальным слоем. Насколько я понимаю, Linq-to-Sql настраивается на модель БД при помощи атрибутов, следовательно, например, при изменении имени поля, мне приходится заниматься перегенерацией классов и перекопиляцией. Я уже и молчу про то, что куча настроек теряется при перегенерации (например, касательно участия поля в update'ах) G>>>Вы просто не умеете его готовить. Я юзаю Linq с самого релиза, проблем не возникало. MK>>Не-не-не, так дело не пойдёт. Есть конкретная задача, я её привел в теме, куда ведет ссылка. Прошу, выдайте мне решение. Я хочу удалить объекты из базы, просто по какому-то критерию. G>Не получится никак. Вернее совсем никак. Это противречит реализации Linq2SQL. Я готов мириться с такой вселенской несправедливостью, учитывая кучу других полезностей. G>Если вам нужны все возможности SQL, то используйте SQL, а не Linq.
Ну если бы в мире существовали только два способа работы с БД: Linq и SQL, то да, юзал бы SQL.
Но есть и третий путь
Здравствуйте, MxKazan, Вы писали:
G>>Если вам нужны все возможности SQL, то используйте SQL, а не Linq. MK>Ну если бы в мире существовали только два способа работы с БД: Linq и SQL, то да, юзал бы SQL. MK>Но есть и третий путь
Угу, написать свой Linq. Но вряд ли удастся добиться тойже функциональности, что Linq2SQL.
Некоторые проблемы, существующие в Linq вы можете решить, но получите кучу других проблем.
В вашем случае гораздо проще написать метод, генерирующий нужный SQL код по Query Expression.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, gandjustas, Вы писали:
G>>В вашем случае гораздо проще написать метод, генерирующий нужный SQL код по Query Expression.
L>Это разве проще?!! Это ж процентов 80 Linq2SQL-а.
а)это проще чем писать аналогичный фреймворк с нуля
б)это проще, чем переписывать все приложение на SQL
в)если нужен простой случай выборки в delete (без подзапросов), то это действительно просто
Здравствуйте, gandjustas, Вы писали:
G>>>В вашем случае гораздо проще написать метод, генерирующий нужный SQL код по Query Expression.
L>>Это разве проще?!! Это ж процентов 80 Linq2SQL-а. G>а)это проще чем писать аналогичный фреймворк с нуля
Про какой фреймворк речь — про linq2sql или про тот, что будет по expression tree генерить соответствующий sql
G>б)это проще, чем переписывать все приложение на SQL
Гм. А кто-то предлагал переписать все на sql? Да и не факт что переписать на sql будет сложнее, зависит от размера приложения.
G>в)если нужен простой случай выборки в delete (без подзапросов), то это действительно просто
Посмотри вверх по ветке, с чего началалась речь про delete. Там как раз речь шла про подзапрос, да еще и с агрегатами.
Здравствуйте, MxKazan, Вы писали:
IT>>1. Типизацию работы с данными БД. MK>Ну в этом Linq далеко не первый.
В некотором смысле первый. Дело в том, что преобразованием имени класса в имя поля теперь занимается сам компилятор. Ранее это был ручной или генерируемый код.
MK> При этом в нём и гемора хватает, см. про удаление
. Мне также, например, не понравилось отсутствие того, что в ADO Entity Framework называют концептуальным слоем. Насколько я понимаю, Linq-to-Sql настраивается на модель БД при помощи атрибутов, следовательно, например, при изменении имени поля, мне приходится заниматься перегенерацией классов и перекопиляцией.
А что по-твоему есть типизация?
MK>Я уже и молчу про то, что куча настроек теряется при перегенерации (например, касательно участия поля в update'ах)
С какой стати?
IT>>2. linq 2 objects принципиально изменил способы обработки данных в памяти. MK>Так. Я видимо не в теме. А что принципиального нового linq 2 objects внёс по части "способы обработки данных в памяти"?
Linq 2 Objects внёс декларативность. Т.е. теперь я пишу что я хочу получить, а не как. В результате вместо кучи циклов с перебором списков и словарей у меня декларативная конструкция.
IT>>3. Возможность работать в функциональном стиле с человеческим лицом. MK>Честно говоря, никогда не страдал от отсутствия подобного в C#
Ты и не будешь страдать. Ты же не страдаешь из-за того, что не можешь видеть в инфракрасном диапазоне. Ты этого не умеешь, обходишься без такого умения и не страдаешь. Так же и здесь.
Неясность изложения обычно происходит от путаницы в мыслях.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Хэлкар, Вы писали:
Х>Этюды nikov'a — это все же очень глубококопание — 90% разработчиков не знает ответов на большинство из них и живет себе припеваючи. В спек заглядывать не обязательно — программировать вполне можно прочитав например Троелсена (так сказать спек в разжеванном виде).
Во-первых, не издевайтесь над Трёльсеном (не знаю, хорошо ли он пишет, но всё равно нечего перевирать имя).
Во-вторых, все известные мне языки, которые пытались устранить низкоуровневые «сложности» и объединить сущности «объект» и «адрес объекта», наступили на одни и те же грабли и связывают объекты вместо копирования или наоборот неочевидным для программиста образом. Чем больше будет распространен C#, тем больше анонимов будут задавать одни и те же вопросы на соответствующих форумах. Да что далеко ходить: самое верхнее сообщение на rsdn.dotnet под модным номером 3110110
: «А теперь вопрос — почему при удалении строк из dt также удаляются строки из ViewState? Догадываюсь, что копируется ссылка, а как правильно скопировать, чтобы создалась копия объекта?». Тем более, что грабли замедленного действия: программа компилируется и работает, но тихо редактирует не те данные.
В-третьих, пока C# привязан к одной определенной платформе, он годится только на то, чтобы флудить о нем в ФП, а на сервер пойдут решения, которые при нужде можно будет перенести куда понадобится :-)
Здравствуйте, WolfHound, Вы писали:
WH>>>Не о том речь. Почитай правила поиска имен :maniac: стандарт писали садомазохисты. КЛ>>ничего особенного WH>Это ADL то ничего особенного?
ADL как раз не особенно сложен, а с концепциями C++09 его сделают вообще простым и красивым.
Проблемы вызывает двухфазный поиск имен, что еще и осложняется традиционной неподдержкой его компиляторами, которые мы не станем здесь называть, наподобие MSVC. Частый вопрос в rsdn.cpp: «почему class A<T>: X<T> { A() { f(); } } не работает, а this->f() работает?».
Здравствуйте, Roman Odaisky, Вы писали:
RO>Во-первых, не издевайтесь над Трёльсеном (не знаю, хорошо ли он пишет, но всё равно нечего перевирать имя).
Эндрю Троелсен (Andrew Troelsen) — стандартная трнскрипция. Откуда ваш вариант?
RO>Во-вторых, все известные мне языки, которые пытались устранить низкоуровневые «сложности» и объединить сущности «объект» и «адрес объекта», наступили на одни и те же грабли и связывают объекты вместо копирования или наоборот неочевидным для программиста образом. Чем больше будет распространен C#, тем больше анонимов будут задавать одни и те же вопросы на соответствующих форумах. Да что далеко ходить: самое верхнее сообщение на rsdn.dotnet под модным номером 3110110
: «А теперь вопрос — почему при удалении строк из dt также удаляются строки из ViewState? Догадываюсь, что копируется ссылка, а как правильно скопировать, чтобы создалась копия объекта?». Тем более, что грабли замедленного действия: программа компилируется и работает, но тихо редактирует не те данные.
RO>В-третьих, пока C# привязан к одной определенной платформе, он годится только на то, чтобы флудить о нем в ФП, а на сервер пойдут решения, которые при нужде можно будет перенести куда понадобится
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, MxKazan, Вы писали:
IT>>>1. Типизацию работы с данными БД. MK>>Ну в этом Linq далеко не первый.
IT>В некотором смысле первый. Дело в том, что преобразованием имени класса в имя поля теперь занимается сам компилятор. Ранее это был ручной или генерируемый код.
А какая в сущности разница?
MK>> При этом в нём и гемора хватает, см. про удаление
. Мне также, например, не понравилось отсутствие того, что в ADO Entity Framework называют концептуальным слоем. Насколько я понимаю, Linq-to-Sql настраивается на модель БД при помощи атрибутов, следовательно, например, при изменении имени поля, мне приходится заниматься перегенерацией классов и перекопиляцией.
IT>А что по-твоему есть типизация?
Намёк ясен. Но он не совсем применим к Linq-To-Sql, уж слишком специфично, я написал чего не хватает. Видно и Microsoft это понимает, потому и есть Entity Framework. А проблема с DELETE похоже не имеет простого решения.
MK>>Я уже и молчу про то, что куча настроек теряется при перегенерации (например, касательно участия поля в update'ах)
IT>С какой стати?
Ну вот, например, мне хотелось обновлять объекты в БД так, чтобы генерируемый Sql запрос не проверял изменение остальных полей (имеется ввиду concurrency). Приходилось ручками проставлять почти всем полям класса UpdateCheck в Never. Поменял поле, перегенерил класс и опять давай проставлять. Справедливости ради скажу, это скорее следует отнести к недостаткам Студии.
IT>>>2. linq 2 objects принципиально изменил способы обработки данных в памяти. MK>>Так. Я видимо не в теме. А что принципиального нового linq 2 objects внёс по части "способы обработки данных в памяти"?
IT>Linq 2 Objects внёс декларативность. Т.е. теперь я пишу что я хочу получить, а не как. В результате вместо кучи циклов с перебором списков и словарей у меня декларативная конструкция.
Это понятно, про ФП я читал. Но не очень понятно в чем конкретная новизна по памяти? Речь о локальности данных? Но вообще, IT, я бы хотел еще раз обозначить, что я принципе не против Linq. Хотелось бы просто понимать реальную необходимость этого, реальные плюсы, а не просто как "игрушка для этюдов". Разве это есть гуд, требовать "что", не понимая "как"?
Здравствуйте, MxKazan, Вы писали:
MK>Ну вот, например, мне хотелось обновлять объекты в БД так, чтобы генерируемый Sql запрос не проверял изменение остальных полей (имеется ввиду concurrency). Приходилось ручками проставлять почти всем полям класса UpdateCheck в Never. Поменял поле, перегенерил класс и опять давай проставлять. Справедливости ради скажу, это скорее следует отнести к недостаткам Студии.
Не совсем понятно, что ты имеешь в виду под "перегенерил класс".
Класс генерится при любом изменении в dbml-е (при сохранении), но тогда получается, что update check поменять пообще невозможно, ведь после изменеиния update check-а класс снова будет перегенерен и его снова нужно будет выставлять.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, MxKazan, Вы писали:
MK>>Ну вот, например, мне хотелось обновлять объекты в БД так, чтобы генерируемый Sql запрос не проверял изменение остальных полей (имеется ввиду concurrency). Приходилось ручками проставлять почти всем полям класса UpdateCheck в Never. Поменял поле, перегенерил класс и опять давай проставлять. Справедливости ради скажу, это скорее следует отнести к недостаткам Студии.
L>Не совсем понятно, что ты имеешь в виду под "перегенерил класс". L>Класс генерится при любом изменении в dbml-е (при сохранении), но тогда получается, что update check поменять пообще невозможно, ведь после изменеиния update check-а класс снова будет перегенерен и его снова нужно будет выставлять.
Ыыыы... Это я имел ввиду, генерацию класса дизайнером, когда взял ручками и перетащил из Server Explorer'а
Это всё уже реализация, это можно изъять из обсуждения.
Здравствуйте, MxKazan, Вы писали:
L>>Класс генерится при любом изменении в dbml-е (при сохранении), но тогда получается, что update check поменять пообще невозможно, ведь после изменеиния update check-а класс снова будет перегенерен и его снова нужно будет выставлять. MK>Ыыыы... Это я имел ввиду, генерацию класса дизайнером, когда взял ручками и перетащил из Server Explorer'а MK>Это всё уже реализация, это можно изъять из обсуждения.
А нефик тащить из сервер-эксплорера, он для добавления новых объектов. Хочешь обновлять — обновляй руками.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, MxKazan, Вы писали:
G>>>ЗЫ. Я подобное мнение видел у прожженых C++ников, которые впоследствие перешли на C#. MK>>Можно расслабиться и спокойно общаться. Мой профессиональный опыт — 3 года сплошного C#. Никакого C++.
E>Вот и выросло новое поколение
Отсутствие продакшн-опыта на нативном языке не означает непонимание основных принципов и неумение программировать на нём. До этого было гораздо больше времени, проведённого с Делфи, где и указатели пройдены и WinApi поюзано немало и много еще чего. И на C# общение, например, с MAPI бывало, с маршалиногом managed в unmanaged. Такое вот оно новое поколение, не стесняется
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, MxKazan, Вы писали:
L>>>Класс генерится при любом изменении в dbml-е (при сохранении), но тогда получается, что update check поменять пообще невозможно, ведь после изменеиния update check-а класс снова будет перегенерен и его снова нужно будет выставлять. MK>>Ыыыы... Это я имел ввиду, генерацию класса дизайнером, когда взял ручками и перетащил из Server Explorer'а MK>>Это всё уже реализация, это можно изъять из обсуждения.
L>А нефик тащить из сервер-эксплорера, он для добавления новых объектов. Хочешь обновлять — обновляй руками.
Дык он там генерит массу всего! Боюсь, что поправив ручками, что нибудь да пропущу
Здравствуйте, MxKazan, Вы писали:
L>>А нефик тащить из сервер-эксплорера, он для добавления новых объектов. Хочешь обновлять — обновляй руками.
MK>Дык он там генерит массу всего! Боюсь, что поправив ручками, что нибудь да пропущу
Под обновлять ручками я имел в виду, не изменение исходников, которые генерит кастом тул, а изменение объектов в диаграме, там настроек уже не так много.
Здравствуйте, Lloyd, Вы писали:
L>Посмотри вверх по ветке, с чего началалась речь про delete. Там как раз речь шла про подзапрос, да еще и с агрегатами.
А можно ли использовать все возможности запросов в операторе delete?
Я c TSQL плохо знаком, по стандарту SQL-92 возможности фильтрации в delete сильно ограничены.
Может оказаться что на уровне генерации sql по Expression такая проблема не решается вообще.
Здравствуйте, gandjustas, Вы писали: G>А можно ли использовать все возможности запросов в операторе delete?
Да. Всю мощь SQL. G>Я c TSQL плохо знаком, по стандарту SQL-92 возможности фильтрации в delete сильно ограничены.
G>Может оказаться что на уровне генерации sql по Expression такая проблема не решается вообще.
Очевидно, решается. Если можно сделать select, то можно и delete.
Аналогичная задача возникает у нас и при попытке воспользоваться insert into ... select ().
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, gandjustas, Вы писали:
L>>Посмотри вверх по ветке, с чего началалась речь про delete. Там как раз речь шла про подзапрос, да еще и с агрегатами. G>А можно ли использовать все возможности запросов в операторе delete? G>Я c TSQL плохо знаком, по стандарту SQL-92 возможности фильтрации в delete сильно ограничены.
Да особо сложных возможностей и не надо. Достаточно
DELETE FROM tbl WHERE pk IN (тут-любой-запрос)
G>Может оказаться что на уровне генерации sql по Expression такая проблема не решается вообще.
Это еще почему? По моему вполне решается, только вот сложность решения = равна сложности генерации select-оа по expression-ам = ~80%-ов Linq2Sql-я.
Здравствуйте, Хэлкар, Вы писали:
RO>>Во-первых, не издевайтесь над Трёльсеном (не знаю, хорошо ли он пишет, но всё равно нечего перевирать имя). Х>Эндрю Троелсен (Andrew Troelsen) — стандартная трнскрипция.
Ну да, а автора «Фауста» зовут Гоетхе.
Фамилия у него, насколько я понимаю, датского происхождения (Trølsen). Так его сначала и переводили, а потом, когда он стал писать на тему новомодного .NET, издательства бросились в спешке переводить и не осилили даже фамилию. Их же (переводчиков) мы должны благодарить за «перегруженные функции», «.NET программирование» и т. п.
Как бы то ни было, «Troelsen» ни при каких обстоятельствах не произносится ни как «Тройелсен», ни как «Троэлсен». Ты же сам употребил слово «транскрипция», хотя «Троелсен» — это транслитерация, а не транскрипция. Почему «Эндрю», а не «Андрев»?
Здравствуйте, Roman Odaisky, Вы писали:
RO>Во-первых, не издевайтесь над Трёльсеном (не знаю, хорошо ли он пишет, но всё равно нечего перевирать имя).
Все претензии — к издателям. После того, как книга издана, упоминать в разговоре именно то написание фамилии автора, которое укзано на обложке — это вполне нормально. А если где-то нужно вставить ссылку на русское издание в списке литературы, то это будет единственным правильным способом указать фамилию автора.
Здравствуйте, MxKazan, Вы писали:
MK>Отсутствие продакшн-опыта на нативном языке не означает непонимание основных принципов и неумение программировать на нём.
Более правдоподобным выглядит утвеждение: "Наличие продакшн-опыта на нативном языке не означает понимания основных принципов и умения программировать на нем". Вне зависимости от "нативного языка".
MK>Такое вот оно новое поколение, не стесняется
Это свойственно всем новым поколениям.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, gandjustas, Вы писали: G>>А можно ли использовать все возможности запросов в операторе delete? S>Да. Всю мощь SQL.
Всю-всю-всю? И даже каскадные удаления тоже?
Зачем тебе эти тапочки? Нужен SQL — юзай sql. Linq for SQL — Linq. Зачем замешивать — незамешиваемое и вываливать наверх закамуфлированные проблемы несовместимости.
Здравствуйте, GlebZ, Вы писали:
G>>>А можно ли использовать все возможности запросов в операторе delete? S>>Да. Всю мощь SQL. GZ>Всю-всю-всю? И даже каскадные удаления тоже?
Здравствуйте, MxKazan, Вы писали:
GZ>>Зачем тебе эти тапочки? Нужен SQL — юзай sql. Linq for SQL — Linq. Зачем замешивать — незамешиваемое и вываливать наверх закамуфлированные проблемы несовместимости.
MK>Ну вот очень огорчает, что Linq 2 SQL устраивает практически всем, но такой банальщины сделать не может
Ну насчет того что это банальщина, это ты загнул. Работа с DataContext подразумевает, что ты сначала меняешт объекты на клиенте. потом делаешь Submit и эти изменения уходят на сервер. Если в DataContext добавить предложенный вариант delete-а, это идиддическая картинка сразу рассыпается в прах.
Здравствуйте, Lloyd, Вы писали:
L>Каскадные удаления не являются частью SQL-я.
Являются частью стандарта. Но вопрос в следующем. Когда мы выполняем delete * from students s where (select min(mark) from exam where exam.studentID = s.id) < 3 мы попадаем в классические грабли ORM. Мы положили на валидацию. Мы не можем сказать какой объект student был уже удален. И мы не можем сказать ваще какие объекты удалены и насколько у нас актуальные данные в памяти поскольку есть триггеры и каскадные удаления. По факту классическая рассинхронизация оперативной памяти и состояния на БД. Подобный запрос только увеличит глубину падения в наших глубинах.
Да и тогда надо вообще ввести генерацию truncate table. Для полноты картины.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Lloyd, Вы писали:
L>>Каскадные удаления не являются частью SQL-я. GZ>Являются частью стандарта.
Но не являются частью языка. А речь о нем.
GZ>Но вопрос в следующем. Когда мы выполняем delete * from students s where (select min(mark) from exam where exam.studentID = s.id) < 3 мы попадаем в классические грабли ORM. Мы положили на валидацию. Мы не можем сказать какой объект student был уже удален. И мы не можем сказать ваще какие объекты удалены и насколько у нас актуальные данные в памяти поскольку есть триггеры и каскадные удаления. По факту классическая рассинхронизация оперативной памяти и состояния на БД. Подобный запрос только увеличит глубину падения в наших глубинах.
RO>Как бы то ни было, «Troelsen» ни при каких обстоятельствах не произносится ни как «Тройелсен», ни как «Троэлсен». Ты же сам употребил слово «транскрипция», хотя «Троелсен» — это транслитерация, а не транскрипция. Почему «Эндрю», а не «Андрев»?
Т.е. проблема в двойной транслитерации — сначала на английский, а потом на русский.
Здравствуйте, GlebZ, Вы писали: GZ>Зачем тебе эти тапочки? Нужен SQL — юзай sql. Linq for SQL — Linq. Зачем замешивать — незамешиваемое и вываливать наверх закамуфлированные проблемы несовместимости.
Очень странная позиция. Вот есть у нас офигенная штука — ЗАпросы Интегрированные в Язык, ЗАИЯ. Преимущества перед SQL вроде бы понятны: статический контроль компилятора, интеллисенс, рефакторинг.
И что, при переходе от select к delete у нас потребности в этих преимуществах внезапно исчезают? Что за фокусы, маэстро, верните зайца обратно!
Вторая претензия у меня именно к "замешиванию незамешиваемого": я правильно понимаю, что предлагается для select, а также одиночных инсертов/апдейтов использовать Linq, а все остальные запросы выполнять на SQL? И всё это в рамках одного приложения? Или имеется в виду, что при первом же появлении delete statement нужно немедленно наложить на себя аскезу, переписать всё на SQL, а арсенал готового кода на linq безвозмездно передать в казну? Надо полагать, теперь он долго не протянет (с).
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
GZ>>Мы положили на валидацию. Мы не можем сказать какой объект student был уже удален. S>Почему? Можем. У нас удалены все объекты, у которых минимальная оценка меньше тройки.
А как определить, что конкретный петя подпадает под это условие? Что если список оценок на клиента еще не загружен?
Здравствуйте, eao197, Вы писали:
G>>>ЗЫ. Я подобное мнение видел у прожженых C++ников, которые впоследствие перешли на C#. MK>>Можно расслабиться и спокойно общаться. Мой профессиональный опыт — 3 года сплошного C#. Никакого C++.
E>Вот и выросло новое поколение
Спокойно! Оно просто еще растет. К тому же не стоит судить обо всех по одному человеку.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Нее. Все хуже. По факту мы не можем полагаться даже на контекст транзакции.
var d=delete * from students s where (select min(mark) from exam where exam.studentID = s.id) < 3
....
var s=select * from students
...
context.Submit();
Уже мы обязаны проверять является ли студент удаленным, или не удаленным. Но трабла в том, что это и почти невозможно проверить. Поскольку нам придется генерить select в соответсвии с правилами delete. А если мы еще до начала изменили сам exam — то ваще невозможно.
Здравствуйте, Lloyd, Вы писали:
MK>>Дык он там генерит массу всего! Боюсь, что поправив ручками, что нибудь да пропущу
L>Под обновлять ручками я имел в виду, не изменение исходников, которые генерит кастом тул, а изменение объектов в диаграме, там настроек уже не так много.
Откровенно говоря, товарищь прав в том, что дизайнер и кодогенераторы (а по мне так и весь подход) студии кривоваты. Но надо все же понимать разницу между самим LINQ и визуальными средствами его поддержки.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Lloyd, Вы писали:
L>А как определить, что конкретный петя подпадает под это условие? Что если список оценок на клиента еще не загружен?
Не надо ничего загружать. Нужно просто сконвертировать linq запрос в sql запрос и передать на сервер для выполнения.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, GlebZ, Вы писали: GZ>Нее. Все хуже. По факту мы не можем полагаться даже на контекст транзакции. GZ>
GZ>var d=delete * from students s where (select min(mark) from exam where exam.studentID = s.id) < 3
GZ>....
GZ>var s=select * from students
GZ>...
GZ>context.Submit();
GZ>
Здесь не вполне ясно, что имеется в виду. Такого синтаксиса в природе не существует. GZ>Уже мы обязаны проверять является ли студент удаленным, или не удаленным.
Не понятно, что значит "проверить". Результат любого запроса однозначно определяется историей всех предыдущих (в том смысле, который задан уровнем изоляции текущей транзакции) запросов. Поскольку никакого lazy load не предполагается, речь идет только о том, чтобы а) подготовить predicate-based delete statement и b) детерминированно его выполнить.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Очень странная позиция. Вот есть у нас офигенная штука — ЗАпросы Интегрированные в Язык, ЗАИЯ. Преимущества перед SQL вроде бы понятны: статический контроль компилятора, интеллисенс, рефакторинг. S>И что, при переходе от select к delete у нас потребности в этих преимуществах внезапно исчезают? Что за фокусы, маэстро, верните зайца обратно!
Зайца бросила хозяйка,
Под мостом остался зайка.
Я совершенно против чтобы из зайца делали бегемота с непонятной мне целью. Ты кстати назвал очень интересное преимущество называемое "рефакторинг". А это означает что сам запрос может быть размазан по коду и инкапсулирован в функции которые не показывают как именно делается запрос. И это налагает обязательства.
Селективные запросы вполне совместимы с такой идеалогией, поскольку мы вполне можем с помощью Identity гарантировать житие транзакции. А вот ежели мы впендюриваемся в запросы без Identity — мы усложняем не только само Linq, но и себе жизнь. Притом на порядок. От этого больше вреда чем пользы.
S>Вторая претензия у меня именно к "замешиванию незамешиваемого": я правильно понимаю, что предлагается для select, а также одиночных инсертов/апдейтов использовать Linq, а все остальные запросы выполнять на SQL? И всё это в рамках одного приложения? Или имеется в виду, что при первом же появлении delete statement нужно немедленно наложить на себя аскезу, переписать всё на SQL, а арсенал готового кода на linq безвозмездно передать в казну? Надо полагать, теперь он долго не протянет (с).
Цезарю — цезарево, авгию — авгиево. Для массированной обработки данных есть процедуры. Не вмещаешься в предложенную концепцию — выходи за пределы. Только вводить такие запросы — это гадить на саму концепцию.
Здравствуйте, Sinclair, Вы писали:
S>Здесь не вполне ясно, что имеется в виду. Такого синтаксиса в природе не существует.
Ну так уж не придирайся. Я не знаю как записать такой delete в Linq. Проблема вполне понятна. GZ>>Уже мы обязаны проверять является ли студент удаленным, или не удаленным. S>Не понятно, что значит "проверить". Результат любого запроса однозначно определяется историей всех предыдущих (в том смысле, который задан уровнем изоляции текущей транзакции) запросов.
Вот в данном случае и непонятен этот результат. То ли то вернет, то ли нет. Для Linq for objects — одно вернет. Для Linq for sql — второе. S>Поскольку никакого lazy load не предполагается, речь идет только о том, чтобы а) подготовить predicate-based delete statement и b) детерминированно его выполнить.
Детерменировано выполнить в рамках контекста. Ибо все запросы выполняются в рамках контекста и несут за собой явную/неявную транзакцию. Человечество потратило столько сил и усилий, чтобы транзакция выполнялось с вполне понятными правилами.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Lloyd, Вы писали:
L>>А как определить, что конкретный петя подпадает под это условие? Что если список оценок на клиента еще не загружен? S>Не надо ничего загружать. Нужно просто сконвертировать linq запрос в sql запрос и передать на сервер для выполнения.
Предположим, что у нас есть класс "Группа", у которой есть свойство-коллекция "Студенты". Что должно произойти с содержимым этой поллекции при удалении студента не напрямую, а опосредованно, через delete-запрос?
Здравствуйте, VladD2, Вы писали:
L>>Под обновлять ручками я имел в виду, не изменение исходников, которые генерит кастом тул, а изменение объектов в диаграме, там настроек уже не так много.
VD>Откровенно говоря, товарищь прав в том, что дизайнер и кодогенераторы (а по мне так и весь подход) студии кривоваты. Но надо все же понимать разницу между самим LINQ и визуальными средствами его поддержки.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, GlebZ, Вы писали:
GZ>>Являются частью стандарта. Но вопрос в следующем. Когда мы выполняем delete * from students s where (select min(mark) from exam where exam.studentID = s.id) < 3 мы попадаем в классические грабли ORM. S>Ничего подобного. Если мы не пытаемся действовать в рамках безнадежно прогнившей концепции FBORM, то всё в порядке.
Здравствуйте, Lloyd, Вы писали:
RO>>Их же (переводчиков) мы должны благодарить за «перегруженные функции», «.NET программирование» и т. п. L>А что не так с перегруженными функциями?
Поиск не работает, где-то здесь было обсуждение, суть которого сводилась к тому, что в начале 1990-х в издательстве «Мир» был составлен хорошо продуманный терминологический словарь для ИТ. Там, в частности, понятие «overloaded function» переводилось как «совмещенные функции», что куда ближе к русскому языку. А потом издательства пришли за самыми дешевыми и быстрыми переводчиками, и те попереводили всё буквально.
Конечно, неприятнее всего видеть английский порядок слов в русских предложениях. Например, «IMAP server» — «Internet Mail Access Protocol server» — это всё существительные. По-русски мы почему-то не говорим «интернет почта доступ протокол сервер», но «IMAP сервер» — сплошь и рядом.
Здравствуйте, nikov, Вы писали:
RO>>Во-первых, не издевайтесь над Трёльсеном (не знаю, хорошо ли он пишет, но всё равно нечего перевирать имя).
N>Все претензии — к издателям. После того, как книга издана, упоминать в разговоре именно то написание фамилии автора, которое укзано на обложке — это вполне нормально. А если где-то нужно вставить ссылку на русское издание в списке литературы, то это будет единственным правильным способом указать фамилию автора.
Какая именно?
Он написал не одну, и российские издательства использовали разные написания.
Здравствуйте, Roman Odaisky, Вы писали:
L>>А что не так с перегруженными функциями?
RO>Поиск не работает, где-то здесь было обсуждение, суть которого сводилась к тому, что в начале 1990-х в издательстве «Мир» был составлен хорошо продуманный терминологический словарь для ИТ. Там, в частности, понятие «overloaded function» переводилось как «совмещенные функции», что куда ближе к русскому языку. А потом издательства пришли за самыми дешевыми и быстрыми переводчиками, и те попереводили всё буквально.
Ты считаешь что "совмещенные" в данном случае лучше чем "перегруженные"?
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, MxKazan, Вы писали:
GZ>>>Зачем тебе эти тапочки? Нужен SQL — юзай sql. Linq for SQL — Linq. Зачем замешивать — незамешиваемое и вываливать наверх закамуфлированные проблемы несовместимости.
MK>>Ну вот очень огорчает, что Linq 2 SQL устраивает практически всем, но такой банальщины сделать не может
L>Ну насчет того что это банальщина, это ты загнул. Работа с DataContext подразумевает, что ты сначала меняешт объекты на клиенте. потом делаешь Submit и эти изменения уходят на сервер. Если в DataContext добавить предложенный вариант delete-а, это идиддическая картинка сразу рассыпается в прах.
Мы все-время рассуждаем в рамках того насколько это легко Linq'у.
Словно не он для меня создан, а я для него
Здравствуйте, Roman Odaisky, Вы писали:
N>>Все претензии — к издателям. После того, как книга издана, упоминать в разговоре именно то написание фамилии автора, которое укзано на обложке — это вполне нормально. А если где-то нужно вставить ссылку на русское издание в списке литературы, то это будет единственным правильным способом указать фамилию автора.
RO>Какая именно? RO>Он написал не одну, и российские издательства использовали разные написания.
На какую книгу ссылаешься, из той книги вариант написания фамилии автора и надо брать для ссылки.
Здравствуйте, Lloyd, Вы писали:
VD>>Откровенно говоря, товарищь прав в том, что дизайнер и кодогенераторы (а по мне так и весь подход) студии кривоваты. Но надо все же понимать разницу между самим LINQ и визуальными средствами его поддержки.
L>Только не надо про nemerle
Причем тут Немерле? Ты давно в отпуске то был?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, MxKazan, Вы писали:
MK>>Не-не-не, так дело не пойдёт. Есть конкретная задача, я её привел в теме, куда ведет ссылка. Прошу, выдайте мне решение. Я хочу удалить объекты из базы, просто по какому-то критерию.
VD>Один раз напиши процедуру удаления и впоследствии пользуйся ею.
Так и было сделано. На Linq в итоге легли только SELECT'ы, благо их было гораздо больше и это работало окейно.
VD>Ответить прямо? ОК, но не обижайся пожалуйста.
Да как-то и в мыслях не было.
VD>Ты не обладаешь достаточными знаниями, чтобы оценить то что тебе дали в руки. VD>Подробнее об этом написано здесь (Парадокс Блаба)
.
VD>Я могу только описать тебе те преимущества которые ты получишь после освоения функционального стиля программирования и понимания (осознания) всех концепций которые с ним связаны. VD>Освоив ФП ты сможешь писать код обработки коллекций в несколько раз более кратко. При этом код будет содержать в несколько раз меньше ошибок. Людям знакомые с ФП будет в несколько раз проще читать твой код, а значит его в несколько раз будет проще поддерживать. VD>Кроме того, если ты проникнешся функциональным подходом, то сможешь смотреть на решение многих задач подругому, на намного более абстрактном уровне.
Ну, откровенно говоря, как посмотришь на кучи сочетаний закорючек, которые приводят, например, здесь
, заявление про выигрышь в читабельности как-то гораздо сомнительнее выглядит. Когда поглядишь во что оно разворачивается, пищеварение совсем нарушается
VD>Для того чтобы воспользоваться преимуществами неизвестной тебе парадигмы нужно сделать немалое напряжение, чтобы понять ее. Проблема в том, что для этого обычно нужно менять мировозрение. Простые, казалось бы, концепции просто не втискиваются в рамки императивного мышления.
Вопрос то не в этом. Пока что большинство аргументов "за" выглядят примерно так: "появилась новая фича, значит она точно необходима и ей нужно пользоваться".
Не опровергая её необходимости, просто хотелось бы увидеть реальные примеры, в которых четко обозначено "было так, не нравилось потому то", "сделал по новому и это решило то-то".
VD>Практически для тебя (для таких как ты) я написал статью — VD>LINQ как шаг к функциональному программированию
. Прочитай ее когда она появится на сайте или если в твоих руках окажется 2-ой номер RSDN Magazine.
G>>>ЗЫ. Я подобное мнение видел у прожженых C++ников, которые впоследствие перешли на C#. MK>>Можно расслабиться и спокойно общаться. Мой профессиональный опыт — 3 года сплошного C#. Никакого C++.
VD>Откровенно говоря тем хуже для тебя. 3 года — это совсем малый срок для нашей профессии, а ты уже становишься ретроградом и отказываешься воспринимать новые (для тебя) знания.
Это, мягко говоря, неверная оценка — я лишь отношусь с подозрением и слушаю более опытных коллег, с которыми работаю.
И между прочим нигде
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, MxKazan, Вы писали:
MK>>Мы все-время рассуждаем в рамках того насколько это легко Linq'у. MK>>Словно не он для меня создан, а я для него GZ>Он создан не для тебя, а для широких слоев населения. Linq for SQL — это концепция. Если бы это был чистый зайа, как говорил Антон, то такие массовые операции вполне подошли бы. Однако он берет на себя еще функцию обеспечения транзакции с помощью identity tracking, и это несколько более мощная концепция чем простой SQLBuilder.(ты ведь уже заметил несовместимость c identity tracking) И обеспечивает потребности более широких слоев населения. Если же сделать мусорку плохо совместимых концепций, то ничего хорошего не получится. Таких примеров — море. GZ>Как и у любого универсального продукта, линка обладает недостатком. Если выходишь за границы концепции, то это потребует некоторых усилий. Так всегда было, и так всегда будет. Большинство путей обходов уже продуманы создателями и предоставлены интерфейсы. Так что по качеству универсализма, IMHO Linq for SQL продукт высшей пробы.
Чего же стоит концепция, если она, упрощая одно, отягощает другое? Никогда бы не подумал, что сделать delete from where — это настолько сугубо индивидуальная задача, что на этот счет можно на заморачиваться ради концепции. Возможно Linq в целом — отличная идея. Однако, раз уж назвался Linq-to-Sql, так и занимайся Sql.
Здравствуйте, MxKazan, Вы писали:
MK>Чего же стоит концепция, если она, упрощая одно, отягощает другое? Никогда бы не подумал, что сделать delete from where — это настолько сугубо индивидуальная задача, что на этот счет можно на заморачиваться ради концепции. Возможно Linq в целом — отличная идея. Однако, раз уж назвался Linq-to-Sql, так и занимайся Sql.
Не. вы просто выделение неправильно сделали: Linq-to-Sql — это прежде всего Linq, т.е. язык запросов.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, MxKazan, Вы писали:
MK>>Чего же стоит концепция, если она, упрощая одно, отягощает другое? Никогда бы не подумал, что сделать delete from where — это настолько сугубо индивидуальная задача, что на этот счет можно на заморачиваться ради концепции. Возможно Linq в целом — отличная идея. Однако, раз уж назвался Linq-to-Sql, так и занимайся Sql.
L>Не. вы просто выделение неправильно сделали: Linq-to-Sql — это прежде всего Linq, т.е. язык запросов.
Не надо ко мне на вы, лучше на ты
Linq — концепция. Sql — назначение. Разве не так? Если бы он был как раз языком запросов, моей проблемы судя по всему бы не было
Здравствуйте, MxKazan, Вы писали:
L>>Не. вы просто выделение неправильно сделали: Linq-to-Sql — это прежде всего Linq, т.е. язык запросов.
MK>Не надо ко мне на вы, лучше на ты MK>Linq — концепция. Sql — назначение. Разве не так? Если бы он был как раз языком запросов, моей проблемы судя по всему бы не было
Почему не было бы? Linq — язык запросов, синтаксиса для update/delete у него нет
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, MxKazan, Вы писали:
L>>>Не. вы просто выделение неправильно сделали: Linq-to-Sql — это прежде всего Linq, т.е. язык запросов.
MK>>Не надо ко мне на вы, лучше на ты MK>>Linq — концепция. Sql — назначение. Разве не так? Если бы он был как раз языком запросов, моей проблемы судя по всему бы не было
L>Почему не было бы? Linq — язык запросов, синтаксиса для update/delete у него нет
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Sinclair, Вы писали:
S>>Здравствуйте, Lloyd, Вы писали:
L>>>А как определить, что конкретный петя подпадает под это условие? Что если список оценок на клиента еще не загружен? S>>Не надо ничего загружать. Нужно просто сконвертировать linq запрос в sql запрос и передать на сервер для выполнения.
L>Предположим, что у нас есть класс "Группа", у которой есть свойство-коллекция "Студенты". Что должно произойти с содержимым этой поллекции при удалении студента не напрямую, а опосредованно, через delete-запрос?
Это вполне можно оставить на разработчика. Если его будет интересовать состояние коллекции "Студенты", то он ее перечитает.
Здравствуйте, MxKazan, Вы писали:
L>>Предположим, что у нас есть класс "Группа", у которой есть свойство-коллекция "Студенты". Что должно произойти с содержимым этой поллекции при удалении студента не напрямую, а опосредованно, через delete-запрос?
MK>Это вполне можно оставить на разработчика. Если его будет интересовать состояние коллекции "Студенты", то он ее перечитает.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, MxKazan, Вы писали:
L>>>Предположим, что у нас есть класс "Группа", у которой есть свойство-коллекция "Студенты". Что должно произойти с содержимым этой поллекции при удалении студента не напрямую, а опосредованно, через delete-запрос?
MK>>Это вполне можно оставить на разработчика. Если его будет интересовать состояние коллекции "Студенты", то он ее перечитает.
L>Как? И как он узнает, что именно надо перечитать?
Эээ... а что, человек работает с БД не зная о ёё структуре?
Здравствуйте, MxKazan, Вы писали:
L>>>>Предположим, что у нас есть класс "Группа", у которой есть свойство-коллекция "Студенты". Что должно произойти с содержимым этой поллекции при удалении студента не напрямую, а опосредованно, через delete-запрос?
MK>>>Это вполне можно оставить на разработчика. Если его будет интересовать состояние коллекции "Студенты", то он ее перечитает.
L>>Как? И как он узнает, что именно надо перечитать?
MK>Эээ... а что, человек работает с БД не зная о ёё структуре?
Не о стурктуре речь. Даже если предположить, что он ее знает, не факт, что он знает о всех загруженных в данный момент в память "Группах".
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, MxKazan, Вы писали:
L>>>>>Предположим, что у нас есть класс "Группа", у которой есть свойство-коллекция "Студенты". Что должно произойти с содержимым этой поллекции при удалении студента не напрямую, а опосредованно, через delete-запрос?
MK>>>>Это вполне можно оставить на разработчика. Если его будет интересовать состояние коллекции "Студенты", то он ее перечитает.
L>>>Как? И как он узнает, что именно надо перечитать?
MK>>Эээ... а что, человек работает с БД не зная о ёё структуре?
L>Не о стурктуре речь. Даже если предположить, что он ее знает, не факт, что он знает о всех загруженных в данный момент в память "Группах".
Ну это уже скорее вопросы проектирования. Удалять что-то, не понимая к чему это может привести — неправильный метод. Такой случай я и не рассматриваю.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Sinclair, Вы писали:
S>>Здравствуйте, Lloyd, Вы писали:
L>>>А как определить, что конкретный петя подпадает под это условие? Что если список оценок на клиента еще не загружен? S>>Не надо ничего загружать. Нужно просто сконвертировать linq запрос в sql запрос и передать на сервер для выполнения.
L>Предположим, что у нас есть класс "Группа", у которой есть свойство-коллекция "Студенты". Что должно произойти с содержимым этой поллекции при удалении студента не напрямую, а опосредованно, через delete-запрос?
гм. то же, что в случае когда эта коллекция есть в кеше другого клиента. ты никогда не узнаешь, актуальные ли данные у тебя в данный момент. они теряют актуальность на момент, когда выплевываются из базы (читай заканчивается транзакция)
Здравствуйте, MxKazan, Вы писали:
L>>Не о стурктуре речь. Даже если предположить, что он ее знает, не факт, что он знает о всех загруженных в данный момент в память "Группах".
MK>Ну это уже скорее вопросы проектирования. Удалять что-то, не понимая к чему это может привести — неправильный метод.
А если удаляя что-то мы всегда должны помнить, на что это может повлиять, то получаем высокую связность. Что тоже не хорошо.
Так что, как ни крути, а ничего хорошего от добавления удаления без предварительно загрузки в память — не получается.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, MxKazan, Вы писали:
L>>>Не о стурктуре речь. Даже если предположить, что он ее знает, не факт, что он знает о всех загруженных в данный момент в память "Группах".
MK>>Ну это уже скорее вопросы проектирования. Удалять что-то, не понимая к чему это может привести — неправильный метод.
L>А если удаляя что-то мы всегда должны помнить, на что это может повлиять, то получаем высокую связность. Что тоже не хорошо. L>Так что, как ни крути, а ничего хорошего от добавления удаления без предварительно загрузки в память — не получается.
Ну собственно, вынуждая нас запрашивать из БД, то что мы и без того хотим удалить, Linq данную проблему никак не решает, потому что сюда
Здравствуйте, MxKazan, Вы писали:
MK>Ну это уже скорее вопросы проектирования. Удалять что-то, не понимая к чему это может привести — неправильный метод. Такой случай я и не рассматриваю.
Здря. Linq предоставляет возможности по декомпозиции. А это значит что часть запросов или даже часть запроса может быть перенесена в другой кусок кода. Не нужно в голове держать полную последовательность действий.
Здравствуйте, MxKazan, Вы писали:
L>>А если удаляя что-то мы всегда должны помнить, на что это может повлиять, то получаем высокую связность. Что тоже не хорошо. L>>Так что, как ни крути, а ничего хорошего от добавления удаления без предварительно загрузки в память — не получается.
MK>Ну собственно, вынуждая нас запрашивать из БД, то что мы и без того хотим удалить, Linq данную проблему никак не решает, потому что сюда
Есть такое. Но если с рассогласованностью кэшей у разных клиентов еще как-то можно смириться, то с рассогласованностью с самим собой — это уже по-моему чрезчур.
Здравствуйте, MxKazan, Вы писали:
MK>Ну собственно, вынуждая нас запрашивать из БД, то что мы и без того хотим удалить, Linq данную проблему никак не решает, потому что сюда
.
Почему не решает? Вполне решает. Просто тут важны приоритеты. Транзакция которая закончилась неуспешно, и не смогла перевести базу данных в несогласованное состояние — это почти не зло. Зло — это когда губят базу данных. Если мы выходим за пределы транзакции, то это действительно нужно делать осторожно. Глобальный кэш — это хорошее средство для того чтобы ее загубить. Но если ты не выходишь за пределы транзакции, используешь только те данные которые в данной транзакции получены и не изменены другой транзакцией до фиксации (что опасно в кэше), то проблемы как таковой — нет. Средств для обеспечения согласованности, тот же DbContext — вполне достаточны.
[]
L>Есть такое. Но если с рассогласованностью кэшей у разных клиентов еще как-то можно смириться, то с рассогласованностью с самим собой — это уже по-моему чрезчур.
Здравствуйте, Константин Л., Вы писали:
L>>Есть такое. Но если с рассогласованностью кэшей у разных клиентов еще как-то можно смириться, то с рассогласованностью с самим собой — это уже по-моему чрезчур.
КЛ>но тогда, по твоим словам, проблема не решаема
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Константин Л., Вы писали:
L>>>Есть такое. Но если с рассогласованностью кэшей у разных клиентов еще как-то можно смириться, то с рассогласованностью с самим собой — это уже по-моему чрезчур.
КЛ>>но тогда, по твоим словам, проблема не решаема
L>которая из?
1. использовать линк
2. грохать каким-то образом объекты
3. "не поломать" загруженные объекты
Здравствуйте, Константин Л., Вы писали:
L>>>>Есть такое. Но если с рассогласованностью кэшей у разных клиентов еще как-то можно смириться, то с рассогласованностью с самим собой — это уже по-моему чрезчур.
КЛ>>>но тогда, по твоим словам, проблема не решаема
L>>которая из?
КЛ>1. использовать линк КЛ>2. грохать каким-то образом объекты КЛ>3. "не поломать" загруженные объекты
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Константин Л., Вы писали:
L>>>>>Есть такое. Но если с рассогласованностью кэшей у разных клиентов еще как-то можно смириться, то с рассогласованностью с самим собой — это уже по-моему чрезчур.
КЛ>>>>но тогда, по твоим словам, проблема не решаема
L>>>которая из?
КЛ>>1. использовать линк КЛ>>2. грохать каким-то образом объекты КЛ>>3. "не поломать" загруженные объекты
L>Выходит что так.
не может быть
а что там у нас с identity? есть что почитать по Linq internals?
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Константин Л., Вы писали:
L>>>Выходит что так.
КЛ>>не может быть
КЛ>>а что там у нас с identity? есть что почитать по Linq internals?
L>да нет там никаких особо internals. linq прост как пробка.
Здравствуйте, Константин Л., Вы писали:
КЛ>>>не может быть
КЛ>>>а что там у нас с identity? есть что почитать по Linq internals?
L>>да нет там никаких особо internals. linq прост как пробка.
КЛ>ну так с identity то что?
Здравствуйте, nikov, Вы писали:
RO>>Какая именно? RO>>Он написал не одну, и российские издательства использовали разные написания.
N>На какую книгу ссылаешься, из той книги вариант написания фамилии автора и надо брать для ссылки.
А если я хочу сказать: «Некто Тр___сен заявляет, будто неплохо разбирается в .NET»?
Здравствуйте, Lloyd, Вы писали: L>Предположим, что у нас есть класс "Группа", у которой есть свойство-коллекция "Студенты". L>Что должно произойти с содержимым этой поллекции при удалении студента не напрямую, а опосредованно, через delete-запрос?
А с чего что-то должно происходить с классами при удалении объектов?
Если тебя интересует, что произойдет с экземплярами этих классов, то ответ — ничего.
Потому, что эти экземпляры были подняты в память в рамках некоторого запроса; и они актуальны на момент выполнения этого запроса.
Тебя же не беспокоит, что DataTable, зачитанный десять минут назад, не обновляется автомагически оттого, что где-то еще (может быть в другом потоке, в другой транзакции, да и вообще в другом приложении) была выполнена модифицирующая операция? А почему тебя беспокоят студенты и группы?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, GlebZ, Вы писали:
GZ>Ну так уж не придирайся. Я не знаю как записать такой delete в Linq. Проблема вполне понятна.
Проблема — непонятна.
GZ>Вот в данном случае и непонятен этот результат. То ли то вернет, то ли нет. Для Linq for objects — одно вернет. Для Linq for sql — второе.
Не понимаю. Должно всегда возвращаться одно и то же. Если не одно и то же — это баг в реализации.
S>>Поскольку никакого lazy load не предполагается, речь идет только о том, чтобы а) подготовить predicate-based delete statement и b) детерминированно его выполнить. GZ>Детерменировано выполнить в рамках контекста.
Это очевидно. Контекст влияет только на понятие "очередности", которое я упомянул выше. Т.е. мы можем (и должны) полагаться на то, что
а) последующий select запрос в том же контексте будет учитывать эффект от удаления
б) последующие результаты в других контекстах будут либо учитывать, либо не учитывать эффект от удаления в зависимости от их уровня изоляции
Для Linq to objects можно считать, что уровень изоляции всегда dirty read.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, MxKazan, Вы писали:
IT>>>В некотором смысле первый. Дело в том, что преобразованием имени класса в имя поля теперь занимается сам компилятор. Ранее это был ручной или генерируемый код. MK>>А какая в сущности разница?
IT>Комрилятор знает больше. Сгенерированная строковая константа для компилятора всё так же остаётся константой. А поле/свойство класса — это ещё и принадлежность к определённому классу. В принципе, precompile-time генератция может многое, но у неё свои козявки. Идеал же вообще ещё не достигнут, но уже возможен. Так, например, уже сегодня вполне возможно на Немерле генерировать необходимую метаинформацию непосредственно из БД в компайл-тайм
Гм... какая-то безграничная любовь у многих вас к Немерле. Не сотвори себе кумира
MK>>Намёк ясен. Но он не совсем применим к Linq-To-Sql, уж слишком специфично, я написал чего не хватает. Видно и Microsoft это понимает, потому и есть Entity Framework. А проблема с DELETE похоже не имеет простого решения.
IT>По мне, так EF — это чистый маркетинг. Наш ответ Хайберлену. Есть же в конце концов и другие невостребованные технологии у MS вроде того же WWF. Будет ещё одна.
Я её еще не пробовал, только статейки посмотрел. Она в чем-то схожа с фреймворком фирмы, о которой уже писал. У них давно решено и то, что в Linq-to-Sql зовется identity и типизация строгая (но генераторами, да) и простые скрипты можно формировать в терминах бизнес-объектов, но не имея самих объектов в памяти. Это я к тому, что возможно Linq-to-Sql меня не столь радует из-за более раннего знакомства с, на мой взгляд, более сильной технологией. Надеюсь в будущих версиях, Майкрософт всё же улучшит Sql'ную составляющую Линка, допустив при желании его использование именно как генератора.
IT>>>Linq 2 Objects внёс декларативность. Т.е. теперь я пишу что я хочу получить, а не как. В результате вместо кучи циклов с перебором списков и словарей у меня декларативная конструкция. MK>>Это понятно, про ФП я читал. Но не очень понятно в чем конкретная новизна по памяти? Речь о локальности данных?
IT>О декларативности работы с данными. Давай рассмотрим пример, может быть так понятней будет. Пример возьмём не очень сложный, но и не самый простой, т.к. на простых примерах вся мощь линка не так проявляется.
IT>Возьмём финансовую задачку. Допустим у нас есть провайдеры, которые тратят бабло и есть получатели, на которых это бабло списывается. С провайдеров деньги списываются через аккаунты в соответствии с определёнными процентами. Например, провайдер '1111' списывает 20% на аккаунт 'AAAA' и 80% на аккаунт 'BBBB'. Получатели получают свою долю тоже через аккаунты, по такому же принципу, т.е., например, получатель '8888' получает 40% с аккаунта 'AAAA' и 60% с аккаунта 'BBBB'. Наша задача получить массив процентов, в котором будет указано, что провайдер '1111' списывает через аккаунт 'AAAA' столько-то процентов на '8888'.
IT>Ниже приведён код. Метод CalcPercents делает эту работу с помощью linq, метод CalcPercents2 в исполнении C# 2.0.
IT>Обрати внимание, кода на линке в 3 раза меньше и он декларативен, в отличии от императивщины на C# 2.0. А если учесть, что таких вычислений у меня в коде пачками, то выгода linq более чем очевидна.
Мда... Сильно! Ладно, Linq-to-Objects оправдан Пока...
MK>>Но вообще, IT, я бы хотел еще раз обозначить, что я принципе не против Linq. Хотелось бы просто понимать реальную необходимость этого, реальные плюсы, а не просто как "игрушка для этюдов". Разве это есть гуд, требовать "что", не понимая "как"?
IT>Но ты же не говоришь SQL серверу как именно выполнять запросы? Ты говоришь, хочу то-то и то-то, а он уже сам читает с диска или из кеша, оптимизирует запросы и занимается прочими 'как'.
Не совсем, тюнем же план запроса. Если в точности говорить "как", пришлось бы очень много кода писать и боюсь смысла в СУБД тогда было бы совсем мало.
Здравствуйте, Sinclair, Вы писали:
L>>Предположим, что у нас есть класс "Группа", у которой есть свойство-коллекция "Студенты". L>>Что должно произойти с содержимым этой поллекции при удалении студента не напрямую, а опосредованно, через delete-запрос? S>А с чего что-то должно происходить с классами при удалении объектов? S>Если тебя интересует, что произойдет с экземплярами этих классов, то ответ — ничего.
Прочти внимательнее.
S>Потому, что эти экземпляры были подняты в память в рамках некоторого запроса; и они актуальны на момент выполнения этого запроса.
S>Тебя же не беспокоит, что DataTable, зачитанный десять минут назад, не обновляется автомагически оттого, что где-то еще (может быть в другом потоке, в другой транзакции, да и вообще в другом приложении) была выполнена модифицирующая операция? А почему тебя беспокоят студенты и группы?
Я не понимаю твоей логики. У нас есть два решения: в одном есть проблема A, в другом проблемы A и B. Очевидно, что второе решение хуже. А с твоих слов получается, что разницы никакой, т.к. оба решения имеют проблему A. Так что ли?
P.S. Проблема A — рассогласование данных между 2-мя разными DataContext-ами. Проблема A — рассогласование данных между внутри одного DataContext-а.
Здравствуйте, MxKazan, Вы писали:
MK>Гм... какая-то безграничная любовь у многих вас к Немерле. Не сотвори себе кумира
Любовь, это да, но дело не в кумирстве. Немерле можно сравнить с оружием джидаев по сравнению с сегодняшними пукалками, которыми вооружен мэйнстрим
IT>>По мне, так EF — это чистый маркетинг. Наш ответ Хайберлену. Есть же в конце концов и другие невостребованные технологии у MS вроде того же WWF. Будет ещё одна. MK>Я её еще не пробовал, только статейки посмотрел. Она в чем-то схожа с фреймворком фирмы, о которой уже писал. У них давно решено и то, что в Linq-to-Sql зовется identity и типизация строгая (но генераторами, да) и простые скрипты можно формировать в терминах бизнес-объектов, но не имея самих объектов в памяти. Это я к тому, что возможно Linq-to-Sql меня не столь радует из-за более раннего знакомства с, на мой взгляд, более сильной технологией. Надеюсь в будущих версиях, Майкрософт всё же улучшит Sql'ную составляющую Линка, допустив при желании его использование именно как генератора.
Ну понятно. Что-то типа очередного ORM, заточенного под конкретную задачу. Вполне возможно. Мы что-то подобное делали ещё в 2003-м году в IBM, но диапазон задач был таков, что уже под следущую пришлось бы клепать что-то подобное, но своё. Хотя, если потратить на это несколько лет, то наверное можно вылепить ещё один Hibernate.
IT>>Но ты же не говоришь SQL серверу как именно выполнять запросы? Ты говоришь, хочу то-то и то-то, а он уже сам читает с диска или из кеша, оптимизирует запросы и занимается прочими 'как'. MK>Не совсем, тюнем же план запроса. Если в точности говорить "как", пришлось бы очень много кода писать и боюсь смысла в СУБД тогда было бы совсем мало.
Ну ты понял
Неясность изложения обычно происходит от путаницы в мыслях.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Lloyd, Вы писали: L>Я не понимаю твоей логики. У нас есть два решения: в одном есть проблема A, в другом проблемы A и B. Очевидно, что второе решение хуже. А с твоих слов получается, что разницы никакой, т.к. оба решения имеют проблему A. Так что ли? L>P.S. Проблема A — рассогласование данных между 2-мя разными DataContext-ами. Проблема A — рассогласование данных между внутри одного DataContext-а.
Так, я понял, в чем дело. Ты подразумеваешь под контекстом DataContext, т.е. кэш с identity tracking. А я подразумеваю контекст транзакции, а identity tracking считаю вредной придумкой. Вообще идея "давайте поднимем объекты в память, там их поредактируем, и опустим обратно" мне не очень нравится. Она плохо отражает реальные события. С ее помощью невозможно сделать традиционные для RDBMS вещи типа элементарного update account set balance = balance + @amount.
Я понимаю, зачем она была сделана, но я бы, наверное, предпочел еще более lightweight реализацию, которая по честному является тонкой оболочкой над SQL. Зато с поддержкой всех четырех стейтментов.
И я, кстати, подозреваю, что это таки возможно в рамках ЗАИЯ.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
L>>Я не понимаю твоей логики. У нас есть два решения: в одном есть проблема A, в другом проблемы A и B. Очевидно, что второе решение хуже. А с твоих слов получается, что разницы никакой, т.к. оба решения имеют проблему A. Так что ли? L>>P.S. Проблема A — рассогласование данных между 2-мя разными DataContext-ами. Проблема A — рассогласование данных между внутри одного DataContext-а.
S>Так, я понял, в чем дело. Ты подразумеваешь под контекстом DataContext, т.е. кэш с identity tracking. А я подразумеваю контекст транзакции, а identity tracking считаю вредной придумкой. Вообще идея "давайте поднимем объекты в память, там их поредактируем, и опустим обратно" мне не очень нравится. Она плохо отражает реальные события. С ее помощью невозможно сделать традиционные для RDBMS вещи типа элементарного update account set balance = balance + @amount.
Это всего лишь говорит о том, что при работе через DataContext, не нужно работать в обход него. Проблемы будут неминуемы. А поэтому и нет необходимости delete по expression-у в DataContext-е.
S>Я понимаю, зачем она была сделана, но я бы, наверное, предпочел еще более lightweight реализацию, которая по честному является тонкой оболочкой над SQL. Зато с поддержкой всех четырех стейтментов. S>И я, кстати, подозреваю, что это таки возможно в рамках ЗАИЯ.
Здравствуйте, IT, Вы писали:
IT>Любовь, это да, но дело не в кумирстве. Немерле можно сравнить с оружием джидаев по сравнению с сегодняшними пукалками, которыми вооружен мэйнстрим
Оружие Джедаев — это такая светящаяся палка, которая на раз сносится мейнстримовой ядерной бомбой вместе с самими Джедаями?
Здравствуйте, VoidEx, Вы писали:
VE>Оружие Джедаев — это такая светящаяся палка, которая на раз сносится мейнстримовой ядерной бомбой вместе с самими Джедаями?
Джедай это такой навороченный спецназ... И современное ополчение с пукалками он зарулит на раз.
А против ядерной бомбы звезда смерти есть...
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Sinclair, Вы писали:
L>>А поэтому и нет необходимости delete по expression-у в DataContext-е. S> Логика на высоте. "Новая помада не подошла к цвету машины, поэтому я пошла пешком".
S>Я всё еще не вижу причин, по которой ты считаешь identity tracking заметно лучше, чем прямое отображение insert/update/delete в SQL.
я так не считаю, я считаю что DataContext (c identity tracking) лучше чем DataContext(Sinclair edition) (c identity tracking и delete-ами через expression в обном флаконе).
Так надеюсь понятнее?
S>Судя по переписке в другой ветке, твоя ментальная модель работы с данными именно такая: "загрузить-изменить-записать". Причем последнюю часть пусть думает DataAdapter, у него работа такая. Это радикально отличается от идеологии SQL; датаадаптер в датасетах и идентити трэкинг в линке пытаются натянуть идеологию "работы через курсор", привычную по Delphi, Access, FoxPro и прочим технологиям восьмидесятых, на запрос-ориентированную клиент-серверную технологию SQL.
Вот только подтасовывать не надо, пожалуйста. Работа с курсорами подразумевает блорирование данных на время редактирования. Именно из-за этого блокирования этот подход и был признан тупиковым. В случае DataContext-а ничего похожего, никаких курсоров и тормозов связанных с ним нет.
S>Вся идея SQL — в том, что нет такой операции "поредактировать результат запроса". Есть update table. Это совсем не то же самое. S>Как я могу поапдейтить результат запроса select student, avg(mark) from ... group by student?
Ну так и не апдейть. В чистом сиквеле тоже есть возможность вызвать update для view, но только если там агрегат будет ты так же и обломишься.
S>В update table я прямо указываю, какие колонки я хочу поредактировать, и зачем. S>Датаадаптер пытается вычислить за меня последовательность действий, которые я имел в виду. Иногда ему это удается. Но принципиальная проблема как раз в том, что выразительность семантики "сохранить объект" недостаточна.
Мне пока хватает. И за десять лет мне как-то не доводилось сталкиваться с проектами, где это действительно было надо. Может быть за исключением только случаев, когда были массовые операции, в этих случаях применение plain sql-я было вполне оправдано. Но такого рода задачи, к счастью не так часть встречаются.
S>Вот было бы наоборот — было бы хорошо. Точно так же как сам update в sql не требует указывать подробности на уровне файлов, любая механика поверх SQL должна по идее нас изолировать от несущественных подробностей. Увы, пока что все эти припрыгивания изолируют нас от существенных подробностей.
В ничтожно малом кол-ве сценариев.
P.S. На досуге рекомендую подумать в каких сценариям DataContext может даже и способствовать перформансу. Подсказка: погугли по "unit of work".
Здравствуйте, Mirrorer, Вы писали:
M>Здравствуйте, MxKazan, Вы писали:
MK>>Вопрос то не в этом. Пока что большинство аргументов "за" выглядят примерно так: "появилась новая фича, значит она точно необходима и ей нужно пользоваться". MK>>Не опровергая её необходимости, просто хотелось бы увидеть реальные примеры, в которых четко обозначено "было так, не нравилось потому то", "сделал по новому и это решило то-то".
M>Ну например. Возьмем простой пример. Просуммировать список чисел
M>Идея какая такой операции. Пробежать по всем элементам списка и сложить все в сумму. M>То бишь аккумулировать результат.
M>И что видно ? Видно дублирование кода. Отличие только в начальном значении суммы и функции, которая будет применяться на каждом шаге. M>Хорошо было бы иметь возможность указывать только эту информацию, без того, чтобы каждый раз писать foreach
M>И все эти функции появившиеся в третьем шарпе злостные баяны в ФП мире, которые по чуть-чуть перетягиваются в мейнстрим. И для того, чтобы понять какие возможности они открывают, надо глядеть на функциональные языки. M>Такие дела.
Спасибо, Mirrorer. Вот пример так пример про суммирование и сложение элементов — простой и понятный, очень понравилось.
Только всё же выскажу, что эти var'ы прямо глаза коробят, того и гляди о типизации думать перестанем
P.S. Гы. И здесь это любимое на всяких музыкальных тру-форумах слово "мейнстрим"
Здравствуйте, eao197, Вы писали:
E>Пока из ваших объяснений я так и не понял, чтоже именно произойдет с объектами A и B. Такое впечатление, что они либо остануться жить вечно, либо их финализаторы гарантированно вызовутся раньше очистки памяти.
Вызов финализатора не гарантирован.
Тут просто надо понимать, что есть финализация. Финализация — это просто некий сервис, который вызывается для объекта после того как GC решит, что объект является претендентом на вылет, и (обязательное условие!) объект был предварительно подписан на этот сервис. В самом коде финализатора объект может принять решение о том, что он еще жив, например, сохранить ссылку на себя в глобальной переменной или в некоем живом объекте. Так вот, в следующий раз, когда этот объект попадёт в лапы сборщика мусора, финализатор для данного объекта уже вызван не будет, если до этого события кто-нить не вызовет для объекта GC.ReRegisterForFinalize(obj);
В принципе, возможна такая ситуция, что на объект уже нигде нет ссылок, а он в своём коде финализатора вновь и вновь самоподписывается на финализацию. На основе этого фокуса можно написать простенький сборщик статистики, как часто происходит GC.
Что касается освобождения памяти, занимаемой объектами. На объект не должны ссылаться ни обычные объекты, ни находящиеся в очереди финализации, таким образом гарантируется, что освобождаемая область памяти более программно недоступна. Вся схема работает вполне надёжно, т.к. нет конкурирующих процессов сборки мусора или конкурирующих тредов финализации.
Здравствуйте, MxKazan, Вы писали:
S>>>Я всё еще не вижу причин, по которой ты считаешь identity tracking заметно лучше, чем прямое отображение insert/update/delete в SQL.
L>>я так не считаю, я считаю что DataContext (c identity tracking) лучше чем DataContext(Sinclair edition) (c identity tracking и delete-ами через expression в обном флаконе). L>>Так надеюсь понятнее?
MK>Lloyd, по-моему, Sinclair имеет ввиду, что ему не нужно identity tracking, если оно мешает выполнять типовые запросы БД. Получилась концепция частично ради самой себя — пользоваться можно, но то здесь, то там приходиться извращаться для решения типовых задач.
Но то, что ему не нужно identity tracking — еще не повод пихать в DataContext чуждый ему (DataContext-у) метод работы с данными.
Здравствуйте, Mirrorer, Вы писали:
M>Ну а как иначе. Большинство идей, которые попадают в языки, были описаны в академических исследованиях 19.. лохматого года. А потом по чуть-чуть из башен слоновой кости идеи перетекают в индустрию в пережеванном и удобном для употребления виде.
Надо только заметить, что далеко не все и далеко не всегда в изначальном виде.
, заявление про выигрышь в читабельности как-то гораздо сомнительнее выглядит. Когда поглядишь во что оно разворачивается, пищеварение совсем нарушается
У проблемы читабельности есть два аспекта.
1. Чтобы легко читать что-то нужно хорошо знать язык на котором это что-то написано. Скажем, я с трудом читаю на английском и совсем плохо на французском, хотя отдельные французские фразы и понимаю. Точно так же не зная ООП и конкретных особенностей его синтаксиса в конкретном языке можно смотреть на совершенно простой и очевидный код как на ребус.
2. Сложность решаемой задачи и ее абстрагированность. Такова уж природа вещей — сложные и высоко-асбтрактные задачи решать сложнее чем "бытовые" (т.е. конкретные и простые). Когда ты разбирашь "этюд", то ты сталкиваешься в первую очередь не с примером фунциональной записи, а с примером высоко-абстрактной задачи которая сложна для понимания. Если ее решение попытаться записать в императивном виде, то скорее всего мы получим кучу кода который в целом будет совсем не понятен. Учитывая же пункт 1 функциональная запись создает для тебя некий ореол таинственности и даже враждебности.
VD>>Для того чтобы воспользоваться преимуществами неизвестной тебе парадигмы нужно сделать немалое напряжение, чтобы понять ее. Проблема в том, что для этого обычно нужно менять мировозрение. Простые, казалось бы, концепции просто не втискиваются в рамки императивного мышления. MK>Вопрос то не в этом. Пока что большинство аргументов "за" выглядят примерно так: "появилась новая фича, значит она точно необходима и ей нужно пользоваться".
Вопрос именно в этом! "Новой фиче" уже исполнилось 50 лет. То что она попала в C# в 2008-ом году не значит, что фичи до этого не было. Просто раньше она вообще была доступна только очень не многим кто захотел и осилил изучение функционального языка.
MK>Не опровергая её необходимости, просто хотелось бы увидеть реальные примеры, в которых четко обозначено "было так, не нравилось потому то", "сделал по новому и это решило то-то".
и (возможно) цикл статей по Немерле (здесь). Уверен, что если приложить небольшое усилие, то не только увидишь примеры, но и осознаешь саму суть, а это намного интереснее.
VD>>Откровенно говоря тем хуже для тебя. 3 года — это совсем малый срок для нашей профессии, а ты уже становишься ретроградом и отказываешься воспринимать новые (для тебя) знания.
MK>Это, мягко говоря, неверная оценка — я лишь отношусь с подозрением и слушаю более опытных коллег, с которыми работаю. MK>И между прочим нигде
Здравствуйте, Lloyd, Вы писали:
L>>>Только не надо про nemerle
VD>>Причем тут Немерле? Ты давно в отпуске то был?
L>Переходить на личности тоже не надо. L>P.S. В отпуске был в июле.
Что значит "тоже"?
У тебя уже мания преследования.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Mirrorer, Вы писали:
M>Ухх. А Немерле значится позволяет автоматизировать Copy&Paste. M>Ну сколько бедный индус может закопипастить за час... А так напишешь M>
M>for x in [1..100000000]
M>CoolMacro()
M>
Бедный индус ошибся. Его код вызвал 100 000 000 раз код всего лишь однажды сгенерированный макросом CoolMacro(). Правильная версия будет выглядеть примерно так:
Здравствуйте, VladD2, Вы писали:
L>>Переходить на личности тоже не надо. L>>P.S. В отпуске был в июле.
VD>Что значит "тоже"?
VD>У тебя уже мания преследования.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Lloyd, Вы писали:
L>>Каскадные удаления не являются частью SQL-я. GZ>Являются частью стандарта. Но вопрос в следующем. Когда мы выполняем delete * from students s where (select min(mark) from exam where exam.studentID = s.id) < 3 мы попадаем в классические грабли ORM. Мы положили на валидацию. Мы не можем сказать какой объект student был уже удален. И мы не можем сказать ваще какие объекты удалены и насколько у нас актуальные данные в памяти поскольку есть триггеры и каскадные удаления. По факту классическая рассинхронизация оперативной памяти и состояния на БД. Подобный запрос только увеличит глубину падения в наших глубинах.
Мы на эти грабли можем наступить еще в тысяче и одном случае, но общее у этих случаев только одно — это независимое изменение источника данных. Оно в любом случае приведет к рассогласованию контекста сессии и источника данных, на что вы, собственно, и указали. И не обязательно выполнять сложные запросы, можно просто работать с базой в соседнем соединении. Вообще, стоит рассматривать объекты в сессии как рассинхронизированные по умолчанию. Поэтому-то линк и выполняет селект перед обновлением источника. Но это можно разрулить, например, версиями записей. В принципе, такая проблема не возникает, если работать с короткими сессиями. Что, впрочем, ЛИНК и предполагает.