Аннотация:
В статье подробно рассматривается состав и способы применения пространства имён Rsdn.Framework.Data, представляющего собой высокоуровневую обёртку над ADO.NET.
30.04.04 06:49: Перенесено из '.NET Projects'
Если нам не помогут, то мы тоже никого не пощадим.
Data Provider for Oracle не добавлен в приведённый выше список не из соображений консолидации с Microsoft в священной борьбе против Oracle, а по причине реализации этого провайдера в отдельной сборке, подключение которой приведёт так же к необходимости её подключения ко всем проектам, которые будут использовать Rsdn.Framework.Data
M>Data Provider for Oracle не добавлен в приведённый выше список не из соображений консолидации с Microsoft в священной борьбе против Oracle, а по причине реализации этого провайдера в отдельной сборке, подключение которой приведёт так же к необходимости её подключения ко всем проектам, которые будут использовать Rsdn.Framework.Data
M>Не понял откуда взялся такой вывод?
Такой вывод взялся после проведения ряда научных экспериментов и получения сообщения вида 'The type 'System.Data.OracleClient.*****' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Data.OracleClient'.', которое появляется в некоторых ситуациях наследования или доступа к мемберам класса, тип которых определён в неподключённой сборке. При текущей архитектуре библиотеки (которая уже успела притерпеть кучу изменений) данная ситуация возможна только при умышленном использовании Oracle провайдера. Т.е. вывод сделан неверно
Спасибо за замечание Статья и библиотека приведены в соответсвие. Заодно для любителей борланды пример подключения провайдера для Oracle заменён на подключение Borland Data Providers for .NET (BDP.NET).
... << RSDN@Home 1.1 beta 2 >>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Игорь Ткачёв, Вы писали:
ИТ>Статья: ИТ>Пространство имён Rsdn.Framework.Data
ИТ>Авторы: ИТ> Игорь Ткачёв
ИТ>Аннотация: ИТ>В статье подробно рассматривается состав и способы применения пространства имён Rsdn.Framework.Data, представляющего собой высокоуровневую обёртку над ADO.NET.
Я вот тут написал свою маленькую либe для создания и выполнения Batch SQL запросов...
думаю что пригодиться всем кто будет разрабатывать серъезные системы: здесь
конечно есть несколько ограничений, но вы зато сможете легко и быстро формировать запросы...
Основная идея:
— запрос может состоять из нескольких последовательных вызовов TSQL stored procedures
— процедуры могут иметь общие параметры
— результат выполнения одной прцедуры может быть передан как параметр в другую процедуру
— вызов может быть сгенерен в виде текста или сделан при помощи встроенных средств NET Framework
— нейтив методы вызова сторед процедур рекомендуеться использовать только для "тяжелых" типов данных таких как image, text, ntext
— после выполнения запроса параметры переданные в запрос и которые имеют [out] маркер вернуться с новыми значениями.
— автоматическая выкачка параметров сторед процедур, что позволяет не заниматьс нудным делом: прописыванием параметров при запросе.
— результат приходит в виде датасета
— все сделано с расчетом на использование при ремоутинге... работа через интерфейсы...
как на меня законченная разработка... может кому идея что доработать в голову прийдет то излагайте...
IT>А можно примерчик как это использовать? а то с телепатическими способностями сегодня как-то туго.
надо тренироваться за пару лет общения на РСДН-не можно не плохие развить
Здравствуйте, Tom, Вы писали:
IT>>А можно примерчик как это использовать? а то с телепатическими способностями сегодня как-то туго. Tom>надо тренироваться за пару лет общения на РСДН-не можно не плохие развить
Телепалке тоже иногда отдых нужен
... << RSDN@Home 1.1 beta 2 >>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, AlexK, Вы писали:
AK>>Я вот тут написал свою маленькую либe для создания и выполнения Batch SQL запросов...
IT>А можно примерчик как это использовать? а то с телепатическими способностями сегодня как-то туго.
все просто до безобразия:
открываеш архив... достаеш сорсы...
ищеш в сорсах файлик: TestSuite.cs и видеш набор тестов на которых гонялась либа...
они же и примеры использования...
Здравствуйте, AlexK, Вы писали:
IT>>А можно примерчик как это использовать? а то с телепатическими способностями сегодня как-то туго.
AK>все просто до безобразия: AK>открываеш архив... достаеш сорсы... AK>ищеш в сорсах файлик: TestSuite.cs и видеш набор тестов на которых гонялась либа... AK>они же и примеры использования...
А... вот оно как. К сожалению, у нас сегодня и с трудолюбием проблема
... << RSDN@Home 1.1 beta 2 >>
Если нам не помогут, то мы тоже никого не пощадим.
ИТ>Авторы: ИТ> Игорь Ткачёв
ИТ>Аннотация: ИТ>В статье подробно рассматривается состав и способы применения пространства имён Rsdn.Framework.Data, представляющего собой высокоуровневую обёртку над ADO.NET.
У меня есть вопрос. К примеру, я хочу исполнить процедуру sp_help, или группу запросов, которая вернёт несколько результатов, и получить списки объектов, связанные с этими результатами. В данный момент, методы ExecuteList и ExecuteSpList делают только один "проход" и не вызывают IDataReader.NextResult.
Может стоит добавить в DbManager метод типа ArrayList GetObjectList(IDataReader reader, Type type).
В таком случае, можно было бы написать так:
IDataReader reader = db.ExecuteSpReader("sp_help", "MyTable");
ArrayList tables = db.GetObjectList(reader, typeof(MyTableInfoClass));
ArrayList columns = db.GetObjectList(reader, typeof(MyColumnInfoClass));
reader.NextResult(); // we are skipping this result set because we want go to index information
reader.NextResult(); // we are skipping this result set because we want go to index information
reader.NextResult(); // we are skipping this result set because we want go to index information
reader.NextResult(); // we are skipping this result set because we want go to index information
ArrayList indexes = db.GetObjectList(reader, typeof(MyIndexInfoClass));
и т.д.
Другой вариант — добавить аргумент Type[] types в методы ExecuteList и ExecuteSpList.
Тогда бы мы имели следующее:
// null type means that we will skip next result set.
Type[] types = new Type[3] {typeof(MyTableInfoClass), typeof(MyColumnInfoClass), null, null, null, typeof(MyIndexInfoClass)}
ArrayList objects = db.ExecuteSpList(types, "sp_help", "MyTable"); // returns ArrayList of ArrayLists
MyTableInfoClass table = (ArrayList[0] as ArrayList)[0];
table.Columns = (ArrayList[1] as ArrayList);
table.Indexes = (ArrayList[5] as ArrayList);
Здравствуйте, Павел Бондарчук, Вы писали:
ПБ>Как вам такая идея?
Добавь в конец MapData.cs следующие методы:
public static IList MapList(IDataReader reader, IList list, Type type)
{
if (reader.Read())
{
Mapping.DataReaderSource drs = new Mapping.DataReaderSource(reader);
Mapping.TypeDescriptor td = Mapping.TypeDescriptor.GetDescriptor(type);
do
{
object o = td.CreateInstance();
MapData.Map(drs, reader, td, o);
list.Add(o);
} while (reader.Read());
}
return list;
}
public static ArrayList MapList(IDataReader reader, Type type)
{
ArrayList arrayList = new ArrayList();
MapList(reader, arrayList, type);
return arrayList;
}
Использовать можно будет так:
using System;
using System.Data;
using System.Collections;
using Rsdn.Framework.Data;
using Rsdn.Framework.Data.DataProvider;
namespace Example
{
public class Category
{
[MapField(Name = "CategoryID")]
public int ID;
public string CategoryName;
[MapField(IsNullable = true)]
public string Description;
}
class Test
{
static void Main()
{
using (DbManager db = new DbManager())
using (IDataReader dr = db.ExecuteReader(@"
SELECT
CategoryID,
CategoryName,
Description
FROM Categories
SELECT
CategoryID,
CategoryName
FROM Categories"))
{
ArrayList al = MapData.MapList(dr, typeof(Category));
foreach (Category c in al)
Console.WriteLine("{0,2} {1,-15} {2}", c.ID, c.CategoryName, c.Description);
if (dr.NextResult())
{
al = MapData.MapList(dr, typeof(Category));
foreach (Category c in al)
Console.WriteLine("{0,2} {1,-15} {2}", c.ID, c.CategoryName, c.Description);
}
}
}
}
}
Я это попозже выложу в новой версии.
... << RSDN@Home 1.1 beta 2 >>
Если нам не помогут, то мы тоже никого не пощадим.
Возвращая IDataReader, вы ставете пользователя перед необходимостью запихивать это в try/catch блок, соответственно заставляете его обрабатывать OleDbException, SqlException, ... и т.д. (Мы же абстрагировались от провайдера?) Это неудобно. Сделайте прокси-класс для IDataReader что бы он выбрасывал только Ваше исключение и сделайте соответственно свою иерархию исключений. Тогда придётся отлавливать только одно исключение.
Первым делом хочется поблагодарить за замечательную библиотечку . Очень интересно и полезно!
Теперь к трабле...
Функция DbManager.CreateParameters() не хочет работать со структурами...
public class testID
{
public int ID;
public testID(int ID)
{
this.ID = ID;
}
}
// .....
IDbDataParameter[] pars =
manager.CreateParameters(new testID(51));
И в итоге имеем параметром со значением, например, 4090216
Щас полезем в исходники ковыряться
Здравствуйте, SiAVoL, Вы писали:
SAV>Теперь к трабле...
Странно, вот такой тест у меня работает как часы
public class testID
{
public int ID;
public testID(int ID)
{
this.ID = ID;
}
}
[Test]
public void CreateParameters()
{
using (DbManager db = new DbManager(ConfigurationString))
{
IDbDataParameter[] pars = db.CreateParameters(new testID(51));
Console.WriteLine(pars[0].Value);
Assert.IsTrue((int)pars[0].Value == 51);
}
}
... << RSDN@Home 1.1 beta 2 >>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, voxel3d, Вы писали:
V> Возвращая IDataReader, вы ставете пользователя перед необходимостью запихивать это в try/catch блок, соответственно заставляете его обрабатывать OleDbException, SqlException, ... и т.д. (Мы же абстрагировались от провайдера?) Это неудобно. Сделайте прокси-класс для IDataReader что бы он выбрасывал только Ваше исключение и сделайте соответственно свою иерархию исключений. Тогда придётся отлавливать только одно исключение.
К сожалению, между исключениями, порождаемыми разнами провайдерами, практически нет ничего общего. Следовательно, всё что можно сделать — это выбрать из такого исключения сообщение и само сообщение сохранить как вложенное. Пользователю всё равно придётся самостоятельно всё это обрабатывать, чтобы добраться до сути. Поэтому, особого смысла изобретать рапер и всё усложнять нет.
... << RSDN@Home 1.1 beta 2 >>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>К сожалению, между исключениями, порождаемыми разнами провайдерами, практически нет ничего общего. Следовательно, всё что можно сделать — это выбрать из такого исключения сообщение и само сообщение сохранить как вложенное. Пользователю всё равно придётся самостоятельно всё это обрабатывать, чтобы добраться до сути. Поэтому, особого смысла изобретать рапер и всё усложнять нет.
Пользователя программы что должно интересовать? Что операция была окончена неудачно. А также возможность отослать разработчику информацию об ошибке. Разработчика что должно интересовать? Возможность получить исчерпывающую информацию об ошибке.
То, что исключения от разных провайдеров очень разные, роли не играет никакой.
try
{
... получение дата ридера
... а также всякие операции с ним
}
catch(Exception e)
{
new ExceptionHandler(e);
}
а внутри класса ExceptionHandler сделайте обработку всех исключений, выдачу понятного пользователю сообщения и создание лога с исчерпывающей информацией. Внутри этого класса в лог скиньте StackTrace обработанный, сообщение об ошибке, ещё если надо что.. Программисту который использует Ваш класс, будет этого достаточно.
Здравствуйте, voxel3d, Вы писали:
V> Пользователя программы что должно интересовать? Что операция была окончена неудачно. А также возможность отослать разработчику информацию об ошибке. Разработчика что должно интересовать? Возможность получить исчерпывающую информацию об ошибке.
Всё так, но только это задача не библиотеки доступа к данным, а как минимум соответствующего слоя.
V>а внутри класса ExceptionHandler сделайте обработку всех исключений, выдачу понятного пользователю сообщения и создание лога с исчерпывающей информацией.
Какого ещё сообщения? А если эта библиотека используется на сервере или в веб приложении?
V>Внутри этого класса в лог скиньте StackTrace обработанный, сообщение об ошибке, ещё если надо что.. Программисту который использует Ваш класс, будет этого достаточно.
Нет, лучше иметь котлеты отдельно, мухи отдельно. Для обработки исключений MS написала специальный MS Exception Management Block, который занимается всеми перечисленными операциями. Подобная библиотека такими вещами заниматься не должна, это всего лишь библиотека, а не сервер приложений.
... << RSDN@Home 1.1 beta 2 >>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Игорь Ткачёв, Вы писали:
ИТ>Статья: ИТ>Пространство имён Rsdn.Framework.Data
ИТ>Авторы: ИТ> Игорь Ткачёв
ИТ>Аннотация: ИТ>В статье подробно рассматривается состав и способы применения пространства имён Rsdn.Framework.Data, представляющего собой высокоуровневую обёртку над ADO.NET.
Есть предложение добавить несколько методов типа:
IDictionary ExecuteDictionary(Type type, string key_field, ...)
чтобы можно было загрузить данные например в Hashtable.
Здравствуйте, gloomy rocker, Вы писали:
GR>Есть предложение добавить несколько методов типа: GR>IDictionary ExecuteDictionary(Type type, string key_field, ...) GR>чтобы можно было загрузить данные например в Hashtable.
Добавим.
... << RSDN@Home 1.1 beta 2 >>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, gloomy rocker, Вы писали:
GR>>Есть предложение добавить несколько методов типа: GR>>IDictionary ExecuteDictionary(Type type, string key_field, ...) GR>>чтобы можно было загрузить данные например в Hashtable.
IT> Добавим.
Здорово! Подожду обновления
Здравствуйте, IT, Вы писали:
IT>К сожалению, между исключениями, порождаемыми разнами провайдерами, практически нет ничего общего.
Вот за это Мелкософту большое человеческое спасибо
IT> Следовательно, всё что можно сделать — это выбрать из такого исключения сообщение и само сообще ние сохранить как вложенное. Пользователю всё равно придётся самостоятельно всё это обрабатывать, чтобы добраться до сути. Поэтому, особого смысла изобретать рапер и всё усложнять нет.
А по моему есть — код который ловит сообщения типа RSDN.Framework.Data.Exceptions гораздо понятнее.
Здравствуйте, migel, Вы писали:
IT>> Следовательно, всё что можно сделать — это выбрать из такого исключения сообщение и само сообще ние сохранить как вложенное. Пользователю всё равно придётся самостоятельно всё это обрабатывать, чтобы добраться до сути. Поэтому, особого смысла изобретать рапер и всё усложнять нет.
M>А по моему есть — код который ловит сообщения типа RSDN.Framework.Data.Exceptions гораздо понятнее.
И, кстати, не только в удобочитаемости дело. Ну не понимаю, зачем абстрагироваться от провайдера, если это делать не до конца.
Здравствуйте, voxel3d, Вы писали:
M>>А по моему есть — код который ловит сообщения типа RSDN.Framework.Data.Exceptions гораздо понятнее.
V> И, кстати, не только в удобочитаемости дело. Ну не понимаю, зачем абстрагироваться от провайдера, если это делать не до конца.
Это не "не до конца", а вообще никак. RSDN.Framework.Data.Exceptions выкидываются только когда что-то не так внутри сомой библиотеки.
Следуя же вашей логики необходимо иметь как минимум два типа исключений: DbManagerException и MapDataException. Первый должен заворачивать исключения провайдеров, второй обрабатывать маппинг. Так?
... << RSDN@Home 1.1 beta 2 >>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Нет, лучше иметь котлеты отдельно, мухи отдельно. Для обработки исключений MS написала специальный MS Exception Management Block, который занимается всеми перечисленными операциями. Подобная библиотека такими вещами заниматься не должна, это всего лишь библиотека, а не сервер приложений.
Нда. А додуматься сделать ещиное дерево исключений они не могли? Опять эти орлы успешно решают проблемы созданные в соседнем отделе.
... << RSDN@Home 1.1 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Вообще-то дело человек говорит.
Раз дело, значит сделаем. Дело же ещё нужно и отстоять и убедить в нём других. Меня уже почти убедили
VD>А нельзя эти МсБлоки прикрутить к твоей библиотеке? Если можно, то привел бы пример...
Exception Managment Block прикручивать нужно к бизнес-слоям, а не к библиотекам. Вот они, например, в Cache его воткнули, а если у меня своя логика обработки исключений? Но он же ведь уже там гвоздями прибит и даже Publish вызывает.
... << RSDN@Home 1.1 beta 2 >>
Если нам не помогут, то мы тоже никого не пощадим.
public static string GetMappedFieldName(
string FieldName, Type BizType)
Она будет возвращать название колонки в БД на которую замаплено свойство FieldName у объекта типа BizType. Т.е. если есть класс
public class BizEntity
{
[MapField("ident")]
public int ID;
public string Name;
}
то GetMappedFieldName("ID", typeof(BizEntity)) будет возвращать "ident".
Если это будет полезно не только мне, конечно...
И вообще в данном направлении можно функциональность порасширить. Можно например еще возвращать StringDictionary с ключем по названиям свойств бизнес-объекта, и значениями — замапленными полями...
ЗЫ: я в принципе и сам могу написать (я там уже глянул, вроде строк на 10 кода ), но хотелось бы это иметь как-то централизованно... А во внешней либе этого, как я понимаю, не сделать. Нужные для этого свойства и классы помечены как internal...
ЗЗЫ: Еще раз благодарю за отличнцю либу! И пользовать приятно и код читать интересно
Здравствуйте, SiAVoL, Вы писали:
SAV>И вообще в данном направлении можно функциональность порасширить. Можно например еще возвращать StringDictionary с ключем по названиям свойств бизнес-объекта, и значениями — замапленными полями...
Все эти внутренности будут раскрыты с возможностью их расширения.
SAV>ЗЗЫ: Еще раз благодарю за отличнцю либу! И пользовать приятно и код читать интересно
Спасибо
Если нам не помогут, то мы тоже никого не пощадим.
Вот еще мысль, вдруг пригодится...
Раз уж появилась обработка исключений, может перехватывать отдельно дедлоки (1205), и перезапускать убиенный запрос, пару раз.
В идеале это должно быть опционально, и с возможностью настравать интервал и количество перезапусков (хотя больше двух раз это уже клиника)
Но с другой стороны это можно и снаружи сделать, если очень надо...
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, Игорь Ткачёв:
M>Вот еще мысль, вдруг пригодится... M>Раз уж появилась обработка исключений, может перехватывать отдельно дедлоки (1205), и перезапускать убиенный запрос, пару раз. M>В идеале это должно быть опционально, и с возможностью настравать интервал и количество перезапусков (хотя больше двух раз это уже клиника)
M>Но с другой стороны это можно и снаружи сделать, если очень надо...
У меня такое впечатление, что если переусердствовать с развитием этой библиотеки в облсти работы с BizEntity, то получим что-то типа System.Data.ObjectSpaces.
Здравствуйте, gloomy rocker, Вы писали:
GR>У меня такое впечатление, что если переусердствовать с развитием этой библиотеки в облсти работы с BizEntity, то получим что-то типа System.Data.ObjectSpaces.
Не, ObjectSpaces — это немного другая... конструкция. Лучше всего TK об этом расскажет.
GR>Может стоит дождаться сабжа?
Ага, годика полтора два...
За это время, либо ишак, либо эмир, либо я...
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, gloomy rocker, Вы писали:
GR>>У меня такое впечатление, что если переусердствовать с развитием этой библиотеки в облсти работы с BizEntity, то получим что-то типа System.Data.ObjectSpaces. M>Не, ObjectSpaces — это немного другая... конструкция. Лучше всего TK об этом расскажет.
Да я и сам почитать могу. Только времени пока нет. Просто показалось что прогресс движется в сторону изобретения очередного велосипеда. Вот и возник такой вопрос. А вообще конечно надо бы уже начинать почитывать про сабж, чтобы в курсе дела быть.
GR>>Может стоит дождаться сабжа? M>Ага, годика полтора два... M>За это время, либо ишак, либо эмир, либо я...
Ну это да. Хотя бетты уже можно пробовать, а если проект долгосрочный, то к моменту его релиза уже выйдут соответствующие релизы Longhorn и Whidby. И все будет круто
Здравствуйте, gloomy rocker, Вы писали:
GR>>>У меня такое впечатление, что если переусердствовать с развитием этой библиотеки в облсти работы с BizEntity, то получим что-то типа System.Data.ObjectSpaces.
Осталось только добавить описание в XML и поддержку абстрактных классов. И то и другое уже почти готово
M>>Не, ObjectSpaces — это немного другая... конструкция. Лучше всего TK об этом расскажет. GR>Да я и сам почитать могу. Только времени пока нет. Просто показалось что прогресс движется в сторону изобретения очередного велосипеда. Вот и возник такой вопрос.
Только пока мы ждём и изобретаем будущий велосипед, MS в своих проектах как раз пользуется Rsdn.Framework.Data
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Игорь Ткачёв, Вы писали:
ИТ>Статья: ИТ>Пространство имён Rsdn.Framework.Data
ИТ>Авторы: ИТ> Игорь Ткачёв
ИТ>Аннотация: ИТ>В статье подробно рассматривается состав и способы применения пространства имён Rsdn.Framework.Data, представляющего собой высокоуровневую обёртку над ADO.NET.
Ну, для начала естественно — спасибо, эта библиотека сэкономила мне кучу времени, которое я уже было начал тратить на написание чего-то подобного, т.к. приложение должно уметь рабртать с несколькими типами БД. Только вот я столкнулся с такой проблемой. Как я понял, библиотека в основном ориентирована на работу с бизнес объектами напрямую. У меня же идет активная работа с датасетами в обе стороны, а никаких функций там не предусмотрено для Update(), оно и в некотором смысле понятно, бо для этого нужно 3 Commands, а сейчас там только 1 на весь инстанс. Собственно, планируется что-нибудь в этом направлении, или может как-то люди обходят использование апдейтов из датасетов какими-то другими эффективными способами? или я просто что-то недопонял
Здравствуйте, Walker, Вы писали:
W>У меня же идет активная работа с датасетами в обе стороны, а никаких функций там не предусмотрено для Update(), оно и в некотором смысле понятно, бо для этого нужно 3 Commands, а сейчас там только 1 на весь инстанс. Собственно, планируется что-нибудь в этом направлении, или может как-то люди обходят использование апдейтов из датасетов какими-то другими эффективными способами? или я просто что-то недопонял
Больше заточено на бизнес-объекты. Но дописать что-то ещё проблем нет, нужны только идеи как это сделать.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, gloomy rocker, Вы писали:
GR>>>>У меня такое впечатление, что если переусердствовать с развитием этой библиотеки в облсти работы с BizEntity, то получим что-то типа System.Data.ObjectSpaces.
IT>Осталось только добавить описание в XML и поддержку абстрактных классов. И то и другое уже почти готово
О!!! Вот это круто. Может еще сделать чтобы можно было генерить схему БД, схему BizEntity и схему мапинга.
Потом все это компилится в сборку. А потом делаем производные классы и начиняем их бизнес логикой.
Методы и свойства, реализующие логику описываются в схеме и в сборке присутствуют как абстрактные.
а так же добавить что-то типа BizRelation и BizConstraint. Вот это будет улет
M>>>Не, ObjectSpaces — это немного другая... конструкция. Лучше всего TK об этом расскажет. GR>>Да я и сам почитать могу. Только времени пока нет. Просто показалось что прогресс движется в сторону изобретения очередного велосипеда. Вот и возник такой вопрос.
IT>Только пока мы ждём и изобретаем будущий велосипед, MS в своих проектах как раз пользуется Rsdn.Framework.Data
Не удивлюсь, если это действительно так. Посмотрел на их "Data Access Application Block" и обнаружил много похожестей , но Rsdn.Framework.Data круче.
Здравствуйте, gloomy rocker, Вы писали:
GR>а так же добавить что-то типа BizRelation и BizConstraint. Вот это будет улет
Это должен быть отдельный продукт.
GR>Не удивлюсь, если это действительно так. Посмотрел на их "Data Access Application Block" и обнаружил много похожестей , но Rsdn.Framework.Data круче.
Ну я на DAAB как бы тоже поначалу поглядывал
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, gloomy rocker, Вы писали:
GR>>а так же добавить что-то типа BizRelation и BizConstraint. Вот это будет улет
IT>Это должен быть отдельный продукт.
А было бы круто
Может обсудим в свободное от безделья время? Только сначала все же надо на ObjectSpaces посмотреть...
GR>>Не удивлюсь, если это действительно так. Посмотрел на их "Data Access Application Block" и обнаружил много похожестей , но Rsdn.Framework.Data круче.
IT>Ну я на DAAB как бы тоже поначалу поглядывал
Да я так и понял.
Здравствуйте, IT, Вы писали:
IT>Больше заточено на бизнес-объекты. Но дописать что-то ещё проблем нет, нужны только идеи как это сделать.
Вообще-то если честно, то я уже там для себя поломал частично код, сделал 4 commands на объект, в нужные ф-и в качестве параметра вставил енум, определяющий какой тип команды использовать (general, insert, delete, update), ну и собсна дописал ф-и для UpdateDataset. Только вот получилось в конце-концов что-то страшное вот исходник ф-и в DbManager (потом дальше пример использования):
/// <summary>
/// Updates database from the given dataset using provided UPDATE, INSERT and
/// DELETE SQL statements with provided parameters.
/// </summary>
/// <param name="dataSet">The DataSet object used to update database.</param>
/// <param name="tableName">The name of the populating table.</param>
/// <param name="updateCommandType">The <see cref="System.Data.CommandType">CommandType</see> (stored procedure, text, etc.) for update operation.</param>
/// <param name="insertCommandType">The <see cref="System.Data.CommandType">CommandType</see> (stored procedure, text, etc.) for insert operation.</param>
/// <param name="deleteCommandType">The <see cref="System.Data.CommandType">CommandType</see> (stored procedure, text, etc.) for delete operation.</param>
/// <param name="updateCommandText">The command text to execute in case of update operation.</param>
/// <param name="insertCommandText">The command text to execute in case of insert operation.</param>
/// <param name="deleteCommandText">The command text to execute in case of delete operation.</param>
/// <param name="updateCommandParameters">An array of paramters used to executes the update command.</param>
/// <param name="insertCommandParameters">An array of paramters used to executes the insert command.</param>
/// <param name="deleteCommandParameters">An array of paramters used to executes the delete command.</param>
/// <returns>The <see cref="DataSet"/>.</returns>public DataSet UpdateDataSet(
DataSet dataSet,
string tableName,
CommandType updateCommandType,
CommandType insertCommandType,
CommandType deleteCommandType,
string updateCommandText,
string insertCommandText,
string deleteCommandText,
IDbDataParameter[] updateCommandParameters,
IDbDataParameter[] insertCommandParameters,
IDbDataParameter[] deleteCommandParameters)
{
PrepareUpdateCommands(updateCommandType,
insertCommandType, deleteCommandType,
updateCommandText, insertCommandText,
deleteCommandText,
updateCommandParameters, insertCommandParameters,
deleteCommandParameters);
return UpdateDataSetInternal(dataSet, tableName);
}
Ну и пример (GetProviderString() достает SQL query):
Как-то очень длинно получилось, теперь вот думаю как это упростить. Как вариант может быть занести CommandType, CommandText и Parameters в отдельную структуру, чтобы все почище получилось и дефолты чтобы хоть какие чтобы проставлять можно было без несчетного количества перегруженных ф-й...
Здравствуйте, gloomy rocker, Вы писали:
IT>>Это должен быть отдельный продукт. GR>А было бы круто GR>Может обсудим в свободное от безделья время? Только сначала все же надо на ObjectSpaces посмотреть...
Давай.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, gloomy rocker, Вы писали:
IT>>>Это должен быть отдельный продукт. GR>>А было бы круто GR>>Может обсудим в свободное от безделья время? Только сначала все же надо на ObjectSpaces посмотреть...
IT>Давай.
Вот только мне не дает покоя мысль, что в итоге получится Rsdn.Framework.Data.DataSet, Rsdn.Framework.Data.DataTable и т.д.
Первым делом хотелось бы поблагодарить за замечательную библиотеку. А вторым делом хотелось бы рассказать про глюк с пулингом, причину которого мне установить не удалось — при использовании библиотеки в компоненте бизнес-логики ежели DBManager не Dispose-ить то из system.data.dll иногда вылетает InvalidOperationException и говорит "A connection pooling error has occured"
Никто с этим не сталкивался ? А то не хочется жить без пулинга
Опыт — это такая вещь, которая появляется сразу после того, как была нужна...
Здравствуйте, gloomy rocker, Вы писали:
GR>Вот только мне не дает покоя мысль, что в итоге получится Rsdn.Framework.Data.DataSet, Rsdn.Framework.Data.DataTable и т.д.
Примерно так и будет, только называться это будет Rsdn.Framework.Data.BizEntity и Rsdn.Framework.Data.BizEntityList
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Больше заточено на бизнес-объекты. Но дописать что-то ещё проблем нет, нужны только идеи как это сделать.
Кстати, если уж на то пошло, то еще пара замеченных проблем:
1. Ну это даже не проблема, а так, неудобство. Не хватает перегруженных ф-й Parameter() чтобы создать конкретный параметр с типом, размером (или без него) и сразу дать ему значение. Т.е. при использовании датасета все нормально, там можно указать sourceColumn, а вот если просто параметр со стороны... если конкретно — вот сигнатура которой не хватает:
public IDbDataParameter Parameter(string parameterName, DbType dbType, object value);
public IDbDataParameter Parameter(string parameterName, DbType dbType, int size, object value);
2. Это больше риторическая проблема. Заключается в том, что для разных провайдеров параметры указываются по-разному. Кому-то надо просто имя, кому-то вопросик, кому-то двоеточие обязательно перед именем параметра (у меня такой для MySql). А так как насколько я понял, библиотека ориентирована на использование с разными провайдерами, хотелось бы чтобы один и тот же запрос проходил одинаково для разных провайдеров. Пока что я это решил тем, что в самом запросе определенным образом помечаю параметр и перед использованием строки запроса заменяю параметр нужной строкой. В интерфейсе для провайдера для этого добавил ф-ю
string AdjustSqlParameter(string parameter);
Она возвращает такое представление параметра, которое нужно этому провайдеру.
Как насчет что-нибудь похожее реализовать у себя?
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, gloomy rocker, Вы писали:
GR>>Вот только мне не дает покоя мысль, что в итоге получится Rsdn.Framework.Data.DataSet, Rsdn.Framework.Data.DataTable и т.д.
IT>Примерно так и будет, только называться это будет Rsdn.Framework.Data.BizEntity и Rsdn.Framework.Data.BizEntityList
Вот, вот! Велосипед форева. Хотя если эту библиотечку снабдить средствами кодогенерации, то может получиться оччень полезная вещь.
Мне например в типизирванном DataSet-е не хватает возможности добавить в какой-нить MyObjectRow собственный метод, реализующий бизнес-логику. Сейчас приходится решать это путем агрегации(наследоваться — себе дороже выйдет). Вот если бы решить эту проблему путем добавления абстрактных методов во время дизайна, а потом реализовать их. Но мне кажется, что в Whidby это(или что-то подобное) уже сделано. То есть если уж делать велосипед, то он должен быть легче DataSet-а, иначе смысла особого нет. А если реализовать все, что использую в DataSet-e, то получится еще один монстр.
M>>Реализовать бы такое грамотно, с использованием Emit. Тогда действительно на ADO.NET можно понемногу забивать.
IT>И генерировать на лету SQL? Тут тебя сразу запинают защитники "правильного" дизайна. И я буду между прочим в их числе
А разве System.DataTable.Select генерирует на лету SQL?
Здравствуйте, gloomy rocker, Вы писали:
GR>Мне например в типизирванном DataSet-е не хватает возможности добавить в какой-нить MyObjectRow собственный метод, реализующий бизнес-логику. Сейчас приходится решать это путем агрегации(наследоваться — себе дороже выйдет). Вот если бы решить эту проблему путем добавления абстрактных методов во время дизайна, а потом реализовать их.
У типизированных датасетов 2 проблемы: non extendable & not reusable. В основном проблема не в самих датасетах, а в генераторе кода.
GR>Но мне кажется, что в Whidby это(или что-то подобное) уже сделано.
Там есть ObjectSpace.
GR>То есть если уж делать велосипед, то он должен быть легче DataSet-а, иначе смысла особого нет. А если реализовать все, что использую в DataSet-e, то получится еще один монстр.
GR>В общем надо определиться с областью применения.
Это правильно.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
W>>2. Это больше риторическая проблема.
IT>В юнит тестах я делаю примерно так же.
W>>Как насчет что-нибудь похожее реализовать у себя?
IT>Как это сделать, чтобы было не коряво
Конечно, не хочется заставлять всех писать на "универсальном" SQL с разметкой параметров. Может, имеет смысл сделать для этого специальный режим? Т.е. если он включен, то делать замену, если нет, ну... ничего страшного
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, mihailik, Вы писали:
M>>А разве System.DataTable.Select генерирует на лету SQL?
IT>Вот ты о чём. Для этого можно ввести тип BizEntityList и делать это в нём. Проще всего на делегатах.
И еще добавить в BizEntityList метод Merge(BizEntityList list) или Merge(BizEntity[] list).
IT>Вот ты о чём. Для этого можно ввести тип BizEntityList и делать это в нём. Проще всего на делегатах.
Оптимально было бы через Reflection.Emit для каждого типа элемента генерировать "проходчик", чтобы он не лез по позднему связыванию читать свойства, а по раннему связыванию обращался и фильтровал.
Правда, такую оптимизацию как индексы тут трудно будет прикрутить.
Конечно, слишком много труда нужно убить на этот SQL-прожект.
Здравствуйте, mihailik, Вы писали:
IT>>Вот ты о чём. Для этого можно ввести тип BizEntityList и делать это в нём. Проще всего на делегатах.
M>Оптимально было бы через Reflection.Emit для каждого типа элемента генерировать "проходчик", чтобы он не лез по позднему связыванию читать свойства, а по раннему связыванию обращался и фильтровал.
Я же тебе говорю — делегаты. И ничего на эмите генерировать не надо.
M>Правда, такую оптимизацию как индексы тут трудно будет прикрутить.
Если не ошибаюсь, то Select из DataTable умеет индексировать таблицу, но к сожалению, как раз для селекта это делается каждый раз. Т.е. каждый раз будет по новой строиться индекс.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, mihailik, Вы писали:
M>Кто знает, не будет ли следующая версия ADO.NET построена на генериках?
В ADO.NET из беты 1.2 никаких генериков нет.
M>В особенности, это может прибавить скорости, если данные по строкам каким-то хитрым способам хранить в структурах. Сейчас-то они боксируются вроде бы.
Данные и так с самого начала хранятся по столбцам в массивах простых типов. Боксинг идет при передаче их в и из DataTable, там шаблонный DataRow.this был бы интересен, но пока что-то движения в эту сторону не видно.
M>>Оптимально было бы через Reflection.Emit для каждого типа элемента генерировать "проходчик", чтобы он не лез по позднему связыванию читать свойства, а по раннему связыванию обращался и фильтровал.
IT>Я же тебе говорю — делегаты. И ничего на эмите генерировать не надо.
На делегатах удобно только с новой версией .NET будет, когда неименованые делегаты будут.
M>>Правда, такую оптимизацию как индексы тут трудно будет прикрутить.
IT>Если не ошибаюсь, то Select из DataTable умеет индексировать таблицу, но к сожалению, как раз для селекта это делается каждый раз. Т.е. каждый раз будет по новой строиться индекс.
Я слышал, что индекс строится в DataView, а не в DataTable.Select.
_>Данные и так с самого начала хранятся по столбцам в массивах простых типов.
Данные хранятся по столбцам?
Очен интерестно. Как-то из самой иерархии классов само собой "следовало", что данные хранятся в DataRow. Кто бы мог подумать!
И что, для NULL отдельный массив заведён на каждый столбец? Определённо нужно это изучить Спасибо за наводку.
Здравствуйте, mihailik, Вы писали:
IT>>Если не ошибаюсь, то Select из DataTable умеет индексировать таблицу, но к сожалению, как раз для селекта это делается каждый раз. Т.е. каждый раз будет по новой строиться индекс.
M>Я слышал, что индекс строится в DataView, а не в DataTable.Select.
Там одни и тот же механизм используется в обоих случаях.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, mihailik, Вы писали:
M>Данные хранятся по столбцам? M>Очен интерестно. Как-то из самой иерархии классов само собой "следовало", что данные хранятся в DataRow. Кто бы мог подумать!
В DataColumn есть указатель на DataStorage, а у того — куча потомков для каждого типа.
M>И что, для NULL отдельный массив заведён на каждый столбец?
Да, битовая карта. Причем пытаются сэкономить скорость и лезут в нее не сразу, а только если в первом массиве ноль
А вот в mono все очень наивно — три массива объектов в DataRow.
Здравствуйте, IT, Вы писали:
M>>И что, для NULL отдельный массив заведён на каждый столбец? Определённо нужно это изучить Спасибо за наводку. IT>В качестве NULL используется DBNull.Value.
Он не влезет в int[]. В DataStorage есть BitArray dbNullBits.
Здравствуйте, mihailik, Вы писали:
IT>>Вот ты о чём. Для этого можно ввести тип BizEntityList и делать это в нём. Проще всего на делегатах.
M>Оптимально было бы через Reflection.Emit для каждого типа элемента генерировать "проходчик", чтобы он не лез по позднему связыванию читать свойства, а по раннему связыванию обращался и фильтровал.
А вместо изобретения велосипеда XPathNavigator не устроит?
Здравствуйте, gloomy rocker, Вы писали:
GR>Может обсудим в свободное от безделья время?
Собственно для дизайнера большой системы я примерно так как ты описал и сделал. Только плюс к тому поддержка WinForms Binding, редактирования элементов в PropertyGrid, реализация IXPathNavigable ну и еще кое что по мелочи.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, gloomy rocker, Вы писали:
GR>>Может обсудим в свободное от безделья время?
AVK>Собственно для дизайнера большой системы я примерно так как ты описал и сделал. Только плюс к тому поддержка WinForms Binding, редактирования элементов в PropertyGrid, реализация IXPathNavigable ну и еще кое что по мелочи.
Здравствуйте, Walker, Вы писали:
W>Здравствуйте, IT, Вы писали:
IT>>Больше заточено на бизнес-объекты. Но дописать что-то ещё проблем нет, нужны только идеи как это сделать.
W>Вообще-то если честно, то я уже там для себя поломал частично код, сделал 4 commands на объект, в нужные ф-и в качестве параметра вставил енум, определяющий какой тип команды использовать (general, insert, delete, update), ну и собсна дописал ф-и для UpdateDataset. Только вот получилось в конце-концов что-то страшное вот исходник ф-и в DbManager (потом дальше пример использования):
А можешь выслать полный код (с PrepareUpdateCommands и UpdateDataSetInternal).
А то мне тоже нужна подобная функциональность. Да и есть пара идей.
Здравствуйте, Alexds, Вы писали:
A>А можешь выслать полный код (с PrepareUpdateCommands и UpdateDataSetInternal). A>А то мне тоже нужна подобная функциональность. Да и есть пара идей.
Здравствуйте, Walker, Вы писали:
W>Здравствуйте, Alexds, Вы писали:
A>>А можешь выслать полный код (с PrepareUpdateCommands и UpdateDataSetInternal). A>>А то мне тоже нужна подобная функциональность. Да и есть пара идей.
W>Без проблем, давай адрес.
Опс. Да, забыл. alexds@yandex.ru
VD>>А нельзя эти МсБлоки прикрутить к твоей библиотеке? Если можно, то привел бы пример...
IT>Exception Managment Block прикручивать нужно к бизнес-слоям, а не к библиотекам. Вот они, например, в Cache его воткнули, а если у меня своя логика обработки исключений? Но он же ведь уже там гвоздями прибит и даже Publish вызывает.
да, да.. не стоит всех насильно пересаживать на блоки путем встраивания их в Rsdn.Data
Здравствуйте, Walker, Вы писали:
W>Здравствуйте, IT, Вы писали:
IT>>Больше заточено на бизнес-объекты. Но дописать что-то ещё проблем нет, нужны только идеи как это сделать.
W>Как-то очень длинно получилось, теперь вот думаю как это упростить. Как вариант может быть занести CommandType, CommandText и Parameters в отдельную структуру, чтобы все почище получилось и дефолты чтобы хоть какие чтобы проставлять можно было без несчетного количества перегруженных ф-й...
А как насчет такого API (в дополнении к твоей ф-ции):
Правда это будет работать при след соглашениях:
1 — В DataSet-e только одно поле первичный ключ (хотя можно добавить ф-ции с IDbDataParameter[] keyField)
2 — Если этот ключ == null , то это вставка записи
3 — Для удаление в процедуру (sql выражение) передается только ID
Вот. Что думаете?
IT — Можно ли что-то подобное добавить?
Здравствуйте, Igor Trofimov, Вы писали:
IT>>Exception Managment Block прикручивать нужно к бизнес-слоям, а не к библиотекам. Вот они, например, в Cache его воткнули, а если у меня своя логика обработки исключений? Но он же ведь уже там гвоздями прибит и даже Publish вызывает.
iT>да, да.. не стоит всех насильно пересаживать на блоки путем встраивания их в Rsdn.Data
Ты о чём?
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Alexds, Вы писали:
A>Вот. Что думаете? A>IT — Можно ли что-то подобное добавить?
Насколько я понял, IT над этой библиотекой работает совсем в другую сторону, и не думаю, что в свою "официальную" версию будет включать поддержку апдейта датасетов, по крайней мере, по той схеме, как это сделал я, т.к. смотрится это криво как-то, хотя и работает IT, правильно я думаю?
А вот самому это сделать на своей версии — никаких проблем, это ж минут 15-20 работы от силы. Если у тебя вдруг не получается, могу помочь. Я это сразу не сделал, бо проект, на котором у меня это используется, работает под Access и MySql, а там процедер нема, вот за ненадобностью и не сделал
Здравствуйте, Walker, Вы писали:
W>Здравствуйте, Alexds, Вы писали:
A>>Вот. Что думаете? A>>IT — Можно ли что-то подобное добавить?
W>Насколько я понял, IT над этой библиотекой работает совсем в другую сторону, и не думаю, что в свою "официальную" версию будет включать поддержку апдейта датасетов, по крайней мере, по той схеме, как это сделал я, т.к. смотрится это криво как-то, хотя и работает IT, правильно я думаю? W>А вот самому это сделать на своей версии — никаких проблем, это ж минут 15-20 работы от силы. Если у тебя вдруг не получается, могу помочь. Я это сразу не сделал, бо проект, на котором у меня это используется, работает под Access и MySql, а там процедер нема, вот за ненадобностью и не сделал
Я бы такую вешь реализовал как дополнительную утилиту. И такм образом, что бы ее можно было пользоватеть( настраивать имена процедур и параметры ) в дизайнере
Здравствуйте, Walker, Вы писали:
W>Здравствуйте, Alexds, Вы писали:
A>>Вот. Что думаете? A>>IT — Можно ли что-то подобное добавить?
W>Насколько я понял, IT над этой библиотекой работает совсем в другую сторону, и не думаю, что в свою "официальную" версию будет включать поддержку апдейта датасетов, по крайней мере, по той схеме, как это сделал я, т.к. смотрится это криво как-то, хотя и работает IT, правильно я думаю?
А что IT скажет?
W>А вот самому это сделать на своей версии — никаких проблем, это ж минут 15-20 работы от силы.
Проблема не в том, чтобы сделать. Просто хочется общего, единого, красивого решения
Здравствуйте, Ведмедь, Вы писали:
В>Я бы такую вешь реализовал как дополнительную утилиту. И такм образом, что бы ее можно было пользоватеть( настраивать имена процедур и параметры ) в дизайнере
Может быть как утилиту, прикручивающуюся отдельно к классу и юзающую его, но как ты это представляешь в дизайнере В дизайнере ты можешь настроить состояние класса, т.е. грубо говоря параметры конструктора и инициализацию мемберов. Здесь же речь идет о вызове отдельной функции. Хотя можно сделать так же как и Command и Adapter в дизайнере, но практика (по крайней мере моя и тех, кого я знаю) показывает, что это никогда в дизайнере не настраивается. Надо ли?
Здравствуйте, Alexds, Вы писали:
W>>А вот самому это сделать на своей версии — никаких проблем, это ж минут 15-20 работы от силы. A>Проблема не в том, чтобы сделать. Просто хочется общего, единого, красивого решения
Так я ж про это и говорю — общее и единое есть, а вот красивости нет
Здравствуйте, Alexds, Вы писали:
A>Проблема не в том, чтобы сделать. Просто хочется общего, единого, красивого решения
А надо ли всё под одну гребенку? Так и будет враппер на враппере сидеть и враппером погонять...
Здравствуйте, Walker, Вы писали:
W>Здравствуйте, Ведмедь, Вы писали:
В>>Я бы такую вешь реализовал как дополнительную утилиту. И такм образом, что бы ее можно было пользоватеть( настраивать имена процедур и параметры ) в дизайнере
W>Может быть как утилиту, прикручивающуюся отдельно к классу и юзающую его, но как ты это представляешь в дизайнере В дизайнере ты можешь настроить состояние класса, т.е. грубо говоря параметры конструктора и инициализацию мемберов. Здесь же речь идет о вызове отдельной функции. Хотя можно сделать так же как и Command и Adapter в дизайнере, но практика (по крайней мере моя и тех, кого я знаю) показывает, что это никогда в дизайнере не настраивается.
Я бы рад их настраивать в дизайнере, да вот в чем загвоздка, там нельзя настраивать какой то обощенный, не привязынный к конкретному провайдеру класс.
Надо ли?
Да надо, примерно как комманд, что то вроде этого.
А по поводу дизайнера... ведь Формы ты же ручками не создаешь в 90% случаев, ты же использвешь дизайнер. Данные о там как апдейтится таблица( а в идеале датасет с указанием того какую таблицу в какое последовательности апдейтит ) являются данными статическими. То есть их хочется сделать декларативными. А вариантов которые первые приходят на ум я виже не много — кодогенерация ( а через дизайнер это можно сделать красиво , и конфигурация ( XML, допустим )
Все руки никак не дойдут, а хотелось бы иметь для апдейта датасета что такое, что настравиваешь в дизайнере, а рантайме создаешь экземпляр и говоришь ему падейт, где два параметра — что апдейтить ( Dataset ) и куда апдейтить ( строка коннекции или обьект, через который идет апдейт, в данном случае из библиотеки Rsdb.Framework.Data.
Я думаю такой механизм был бы удобным, пока нет нового фреймвока и новой студии... там вроде есть что то подобное.
Здравствуйте, mikа, Вы писали:
M>Здравствуйте, Ведмедь, Вы писали:
В>>Я думаю такой механизм был бы удобным, пока нет нового фреймвока и новой студии... там вроде есть что то подобное.
M>Ну это еще не повод останавливать в развитии это библиотеки. Высокоуровневое над высокоуровневум еще никто не отменял Правда, Игорь?
Отвечаю сам себе. Игоря я имел Ткачева. После написания данного поста решил выяснить, а как же по имени товарищ Ведмедь... Вот ведь совпадение!
Здравствуйте, Ведмедь, Вы писали:
В>Я думаю такой механизм был бы удобным, пока нет нового фреймвока и новой студии... там вроде есть что то подобное.
Вообще-то да... Идеальным решением было бы переписывание дизайнера для датасета, точнее написание своего, со встраиванием туда описания механизма апдейта. Но это дюже много работы и думаю оно того не стоит. Достаточно наверное свой дизайнерский контрол, как ты и говоришь, который будет прикручивать инфу для апдейта к конретному инстансу датасета. Только вот вопрос, кто ж это будет делать?
Здравствуйте, orangy, Вы писали:
O>Здравствуйте, Alexds, Вы писали:
A>>Проблема не в том, чтобы сделать. Просто хочется общего, единого, красивого решения O>А надо ли всё под одну гребенку?
Дык... вся идея этой библиотеки чтобы унифицировать доступ к данным и по возможности отвязаться от провайдера.
O>Так и будет враппер на враппере сидеть и враппером погонять...
В разумных пределах врапперы не мешают, а только лишь помогают. До того момента как они продолжают эффективно решать какую-то проблему и делают код чище, почему бы их и не применять? Пока что здесь еще никто не зашел за эту границу (как мне кажется ).
Здравствуйте, mikа, Вы писали:
M>Здравствуйте, mikа, Вы писали:
M>>Здравствуйте, Ведмедь, Вы писали:
В>>>Я думаю такой механизм был бы удобным, пока нет нового фреймвока и новой студии... там вроде есть что то подобное.
M>>Ну это еще не повод останавливать в развитии это библиотеки. Высокоуровневое над высокоуровневум еще никто не отменял Правда, Игорь?
M>Отвечаю сам себе. Игоря я имел Ткачева. После написания данного поста решил выяснить, а как же по имени товарищ Ведмедь... Вот ведь совпадение!
Тогда я еще на пред пост отвечу. Это не повод отсанавливаться в развитии библиотеки, просто не хочется велосипед изобретать Пока его нет, да удобно сделать А когда появится, тогданадо будет думать
Здравствуйте, Walker, Вы писали:
A>>>Проблема не в том, чтобы сделать. Просто хочется общего, единого, красивого решения O>>А надо ли всё под одну гребенку? W>Дык... вся идея этой библиотеки чтобы унифицировать доступ к данным и по возможности отвязаться от провайдера.
Как бы не это было целью создания SQL Унификация приводит к минимализму и ограничениям. К тому же довольно редко бывает так, что нужно настолько явное отвлечение от провайдера, чтобы ни-ни! А когда у тебя вертится MSSQL не очень-то разумно оставаться в рамках MDB...
Вообще, по моему разумения, в RFD три части:
1. Маппер, на мой взгляд самое ценное
2. Провайдеры, просто фабрика объектов для выполнения запросов
3. DbManager, сущность интеграции первого и второго + много полезных перегрузок для упрощения часто встречающихся задач
Таким образом в RFD нет естественного места для работы со схемами таблиц и прочими сущностями выходящими за рамки выполнения запросов к базе. Собственно, DbManager данными не манипулирует, он их получает от провайдера, пропускает через маппер (если нужно) и отдаёт результат. Накручивание подобной функциональности неизбежно ограничит общность RFD. Другое дело, что в частных задачах это всё нужно, но каждому своё. Поэтому, на мой взгляд, нужно двигаться в сторону получения необходимой информации от маппера (что уже делается), как то аттрибуты, информация о маппинге и всё такое, чтобы кому надо мог бы накрутить сверху то, что ему надо.
O>>Так и будет враппер на враппере сидеть и враппером погонять... W>В разумных пределах врапперы не мешают, а только лишь помогают. До того момента как они продолжают эффективно решать какую-то проблему и делают код чище, почему бы их и не применять? Пока что здесь еще никто не зашел за эту границу (как мне кажется ).
"Введение нового уровня абстракции помогает решить все проблемы, кроме слишком большого количества уровней абстракции"
Здравствуйте, orangy, Вы писали:
O>Таким образом в RFD нет естественного места для работы со схемами таблиц и прочими сущностями выходящими за рамки выполнения запросов к базе. Собственно, DbManager данными не манипулирует, он их получает от провайдера, пропускает через маппер (если нужно) и отдаёт результат. Накручивание подобной функциональности неизбежно ограничит общность RFD. Другое дело, что в частных задачах это всё нужно, но каждому своё. Поэтому, на мой взгляд, нужно двигаться в сторону получения необходимой информации от маппера (что уже делается), как то аттрибуты, информация о маппинге и всё такое, чтобы кому надо мог бы накрутить сверху то, что ему надо.
Это все хорошо и никто не отрицает правильности твоих слов. Но давай вернемся к нашим баранам. Библиотека хороша и красива, но вот незадача — позволяет получить датасет из базы, а обратно его туда закинуть — никак. С этого все и началось. Я дописал эту функциональность, но как-то получилось громоздко, и мне даже наверное самому бы не понравилось, если бы кто-то включил такое в библиотеку, но оно работает, и как минимум 2 человека это уже юзают . Естественно встал вопрос по поводу использования хранимых процедур с этим и вообще определения каким образом апдейтить, вставлять, удалять записи из датасета, да так, чтобы определить это в одном месте и забыть. И если ты почитаешь в соседней ветке, никто и не хочет уже вставлять это в библиотеку, это действительно должен быть еще один уровент абстракции Так что мы по-моему спорим ни о чем
O>>>Так и будет враппер на враппере сидеть и враппером погонять... W>>В разумных пределах врапперы не мешают, а только лишь помогают. До того момента как они продолжают эффективно решать какую-то проблему и делают код чище, почему бы их и не применять? Пока что здесь еще никто не зашел за эту границу (как мне кажется ). O>"Введение нового уровня абстракции помогает решить все проблемы, кроме слишком большого количества уровней абстракции"
Вот это вот по-моему единственно, что тебе не нравится, но насколько я вижу, еще никто не поставил здесть проблемы "слишком большого количества уровней абстракции" И опять же, если есть люди, которые считают, что это нужно и облегчит написание кода, почему бы и нет?
Здравствуйте, Walker, Вы писали:
W>Это все хорошо и никто не отрицает правильности твоих слов. <...> Так что мы по-моему спорим ни о чем
Так я и не спорю Просто выразил своё мнение.
Здравствуйте, orangy, Вы писали:
O>Здравствуйте, Walker, Вы писали:
W>>Это все хорошо и никто не отрицает правильности твоих слов. <...> Так что мы по-моему спорим ни о чем O>Так я и не спорю Просто выразил своё мнение.
Ну тогда ты бы лучше выразил свое мнение по той проблеме, что я описал в пред. посте А то я не могу красивого решения найти.
Здравствуйте, Walker, Вы писали:
W>Насколько я понял, IT над этой библиотекой работает совсем в другую сторону, и не думаю, что в свою "официальную" версию будет включать поддержку апдейта датасетов, по крайней мере, по той схеме, как это сделал я, т.к. смотрится это криво как-то, хотя и работает IT, правильно я думаю?
Правильно
W>А вот самому это сделать на своей версии — никаких проблем, это ж минут 15-20 работы от силы. Если у тебя вдруг не получается, могу помочь. Я это сразу не сделал, бо проект, на котором у меня это используется, работает под Access и MySql, а там процедер нема, вот за ненадобностью и не сделал
Даю хинт. От DbManager можно наследоваться.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, mikа, Вы писали:
M>>Ну это еще не повод останавливать в развитии это библиотеки. Высокоуровневое над высокоуровневум еще никто не отменял Правда, Игорь?
Правда.
M>Отвечаю сам себе. Игоря я имел Ткачева. После написания данного поста решил выяснить, а как же по имени товарищ Ведмедь... Вот ведь совпадение!
Просто удивительное совпадение.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
W>>А вот самому это сделать на своей версии — никаких проблем, это ж минут 15-20 работы от силы. Если у тебя вдруг не получается, могу помочь. Я это сразу не сделал, бо проект, на котором у меня это используется, работает под Access и MySql, а там процедер нема, вот за ненадобностью и не сделал
IT>Даю хинт. От DbManager можно наследоваться.
Да ну?? Не поможет, т.к. чтобы сделать возможность апдейта датасетов (более менее красиво), надо немножко перелопатить твои private и non virtual функции, либо в наследнике переписывать все то, что у тебя уже написано. Ни то, ни другое вроде бы не подходит.
Здравствуйте, Walker, Вы писали:
W>Да ну?? Не поможет, т.к. чтобы сделать возможность апдейта датасетов (более менее красиво), надо немножко перелопатить твои private и non virtual функции, либо в наследнике переписывать все то, что у тебя уже написано. Ни то, ни другое вроде бы не подходит.
Это всё негошиэйтэбл. Нужен только список методов, которые нужно сделать protected.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Alexds, Вы писали:
W>>Насколько я понял, IT над этой библиотекой работает совсем в другую сторону, и не думаю, что в свою "официальную" версию будет включать поддержку апдейта датасетов, по крайней мере, по той схеме, как это сделал я, т.к. смотрится это криво как-то, хотя и работает IT, правильно я думаю?
A>А что IT скажет?
В идеале хотелось бы всё делать в редакторе. Например, создаём Component и накладываем на него неких объектов, которым задаём SQL выражение (SP) и список параметров. Т.е. что-то типа рисование DAL в редакторе. Но пока что-то никаких идей как это сделать.
W>>А вот самому это сделать на своей версии — никаких проблем, это ж минут 15-20 работы от силы. A>Проблема не в том, чтобы сделать. Просто хочется общего, единого, красивого решения
Точно, особенно последнего.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, orangy, Вы писали:
O>Таким образом в RFD нет естественного места для работы со схемами таблиц и прочими сущностями выходящими за рамки выполнения запросов к базе. Собственно, DbManager данными не манипулирует, он их получает от провайдера, пропускает через маппер (если нужно) и отдаёт результат. Накручивание подобной функциональности неизбежно ограничит общность RFD.
Всё верно.
К сожалению, чаще всего получается так, что увлечение безграничной функциональностью и безконтрольное добавление фич пораждает таких монстров, которые, в последствии, разваливаясь, хоронят под своими обломками и их создателей. Я ещё хочу жить
Нет никаких проблем добавить дополнительные фичи согласующиеся с текущей функциональностью. Делать же принципиально новые вещи нужно отдельно. Возможно в рамках пространства имён, но обязательно вне класса DbManager.
O> Другое дело, что в частных задачах это всё нужно, но каждому своё. Поэтому, на мой взгляд, нужно двигаться в сторону получения необходимой информации от маппера (что уже делается), как то аттрибуты, информация о маппинге и всё такое, чтобы кому надо мог бы накрутить сверху то, что ему надо.
На сегодняшний день маппер содержит всё необходимое для поддержки фреймворка реализующего как stateless, так и stateful модель (ПСХПП АВК). Так как и первым и вторым я плотно занимаюсь на работе, то всё что я пока смог придумать сам или что мне подсказано вами маппер уже поддерживает. Дальнейший вполне логичный шаг — написание этих самых фреймворков. Но здесь есть одна проблема. Сколько девелоперов, столько и мнений как он должен выглядеть
Если нам не помогут, то мы тоже никого не пощадим.
Я вот тут подумал. А если сделать что-то типа такого:
using (DbManager db = new DbManager())
{
return db
.InsertCommand(commandType, "COMMAND TEXT")
.UpdateCommand(commandType, "COMMAND TEXT")
.DeleteCommand(commandType, "COMMAND TEXT")
.ExecutePreparedDataSet();
}
Тогда можно будет реиспользовать кучу методов.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Тогда можно будет реиспользовать кучу методов.
Не совсем я понял идею... Уже существующие методы при любом раскладе будут работать только с одной command. Да и еще же надо параметры указать для каждой command... И чем это отличается от передачи commands как параметров в функцию? Ведь если я вызываю несколько разных методов Execute... то я скорее всего захочу для каждого иметь свои commands и parameters к ним, так что выставление commands отдельно для инстанса DbManager вряд ли даст много пользы. Что-то я не понял, можешь подробнее?
И кстати, я уже наваял наследника для выполнения апдейтов датасетов, но я это делал для версии 1.1 (изменения для класса DbManager минимальны), сейчас надо только слить для версии 1.2. Сегодня-завтра сделаю — посмотришь мой подход.
Здравствуйте, Walker, Вы писали:
W>Здравствуйте, IT, Вы писали:
IT>>Тогда можно будет реиспользовать кучу методов.
W>Не совсем я понял идею... Уже существующие методы при любом раскладе будут работать только с одной command. Да и еще же надо параметры указать для каждой command... И чем это отличается от передачи commands как параметров в функцию? Ведь если я вызываю несколько разных методов Execute... то я скорее всего захочу для каждого иметь свои commands и parameters к ним, так что выставление commands отдельно для инстанса DbManager вряд ли даст много пользы. Что-то я не понял, можешь подробнее? W>И кстати, я уже наваял наследника для выполнения апдейтов датасетов, но я это делал для версии 1.1 (изменения для класса DbManager минимальны), сейчас надо только слить для версии 1.2. Сегодня-завтра сделаю — посмотришь мой подход.
Вообще-то уже сделал. Необходимые изменения в классе DbManager:
1. Command property -> virtual
2. Close() method -> virtual
3. HandleException(Exception ex) method -> protected
4. AttachParameters(IDbCommand command, IDbDataParameter[] commandParameters) method -> protected
5. Для мембера _commandParameters надо реализовать виртуальную пропертю CommandParameters и ВЕЗДЕ по коду (4 места) заменить обращение к _commandParameters на CommandParameters.
Скажи, если есть какие проблемы с этим. И если интересно скажи на какой адрес прислать исходники.
Здравствуйте, Walker, Вы писали:
W>Не совсем я понял идею... Уже существующие методы при любом раскладе будут работать только с одной command. Да и еще же надо параметры указать для каждой command... И чем это отличается от передачи commands как параметров в функцию? Ведь если я вызываю несколько разных методов Execute... то я скорее всего захочу для каждого иметь свои commands и parameters к ним, так что выставление commands отдельно для инстанса DbManager вряд ли даст много пользы. Что-то я не понял, можешь подробнее?
Проблема вот в чём. Например, мы хотим иметь метод возвращающий датасет и принимающий его в качестве параметра. Теперь мы хотим иметь возможность задавть тип команды либо опускать его и для этих двух вариантов ещё задавать парметры или опускать их. Итого 2 варианта передачи датасета и 4 для параметров. В результате нужно написать 8 перекрытий. Если это разделить на 2 метода, то писать нужно 6 методов. Но это для одной команды. А у нас их три. Теперь посчитай сколько у нас получается комбинаций.
Если же вынести задание команд в отдельные методы, то дальше комбинируй сам как хочешь.
using (DbManager db = new DbManager())
{
return db
.InsertCommand("INSERT INTO...", db.CreateParameters(entity))
.UpdateCommand(CommandType.StoredProcedure, "UpdateItem")
.DeleteSp("DeleteItem", db.Parameter("@ID"))
.UpdateDataSet();
}
Придётся конечно запоминать сформированные команды в DbManager, но это уже мелочи.
W>И кстати, я уже наваял наследника для выполнения апдейтов датасетов, но я это делал для версии 1.1 (изменения для класса DbManager минимальны), сейчас надо только слить для версии 1.2. Сегодня-завтра сделаю — посмотришь мой подход.
Давай.
Если нам не помогут, то мы тоже никого не пощадим.
IT>using (DbManager db = new DbManager())
IT>{
IT> return db
IT> .InsertCommand("INSERT INTO...", db.CreateParameters(entity))
IT> .UpdateCommand(CommandType.StoredProcedure, "UpdateItem")
IT> .DeleteSp("DeleteItem", db.Parameter("@ID"))
IT> .UpdateDataSet();
IT>}
IT>
IT>Придётся конечно запоминать сформированные команды в DbManager, но это уже мелочи.
Аааааа... вот ты про что! Ну да, очень даже неплохо получается. Я правда, уже почти думал реализовывать это у себя более классическим методом — с помощью задания класса для описания команды. Т.е. класс содержит текст, тип команды и параметры. Ф-и Update... принимают 3 объекта такого класса (для каждой команды), не хочешь — ставь null. Недостаток в моем подходе — надо каждый раз создавать дополнительный объект (даже 3), который кушает память. В твоем подходе же просто не совсем понятно, почему InsertCommand должна возвращать DbManager . Выбор за автором библиотеки . Кстати, в моем коде уже вся функциональность имеется, чтобы реализовать оба подхода, за час-полтора можно сделать.
W>>И кстати, я уже наваял наследника для выполнения апдейтов датасетов, но я это делал для версии 1.1 (изменения для класса DbManager минимальны), сейчас надо только слить для версии 1.2. Сегодня-завтра сделаю — посмотришь мой подход.
IT>Давай.
Здравствуйте, IT, Вы писали:
IT>Если же вынести задание команд в отдельные методы, то дальше комбинируй сам как хочешь.
IT>
IT>using (DbManager db = new DbManager())
IT>{
IT> return db
IT> .InsertCommand("INSERT INTO...", db.CreateParameters(entity))
IT> .UpdateCommand(CommandType.StoredProcedure, "UpdateItem")
IT> .DeleteSp("DeleteItem", db.Parameter("@ID"))
IT> .UpdateDataSet();
IT>}
IT>
IT>Придётся конечно запоминать сформированные команды в DbManager, но это уже мелочи.
Еще мысля меня посетила... При таком подходе фактически выставляются команды для инстанса. Если я хочу выполнить два подряд апдейта, то после первого у меня останутся команды, которые для второго например мне нафиг не нужны, т.е. либо надо тогда еще давать ф-и типа RemoveInsertCommand, но тогда в любом случае перед вызовом ф-и апдейта надо будет указывать все 3 команды, чтобы быть уверенным, что будут использоваться именно те команды, которые нужны, либо как вариант можно очищать все команды после выполнения каждой ф-и апдейта, но это тоже как-то не так, бо а что если я все-таки хочу реиспользовать какую-то команду? В общем, вот...
как выполнить сторед процедуру с 2-мя входными и одним выход
Здравствуйте, oRover, Вы писали:
R>как выполнить сторед процедуру с 2-мя входными и одним выходным параметром? R>пробовал ExecuteSpScalar и ExecuteSpList — что-то не получается...
Вот юнит тест output параметра:
[Test]
public void OutputParameter()
{
using (DbManager db = new DbManager(ConfigurationString))
{
db.ExecuteNonQuery(@"
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Test]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
begin
drop procedure [dbo].[Test]
end");
db.ExecuteNonQuery(@"
CREATE PROCEDURE dbo.Test
@p1 int,
@p2 int,
@po int output
AS
SET @po = @p1 * @p2");
db.ExecuteNonQuery(@"
GRANT EXEC ON dbo.Test TO PUBLIC");
db.ExecuteSpNonQuery(
"Test",
db.Parameter("@p1", 2),
db.Parameter("@p2", 2),
db.OutputParameter("@po", 0));
object o = db.Parameter("@po").Value;
Console.WriteLine(o);
Assert.AreEqual(4, o);
}
}
Но, по моему скромному ИМХУ использование output рараметров не самый лучший способ возвращать данные из сохранённой процедуры. Ту же SP можно написать так:
Hello, IT!
DI>> А как насчет добавить параметр таймаут для ExecuteNonQuery, DI>> ExecuteScalar и т.д.?
I> По идее это задаётся в Command.CommandTimeout.
Ну да, но когда мы передаем текст и получаем только результат — доступ к Command мы не имеем...
Здравствуйте, der Igel, Вы писали:
I>> По идее это задаётся в Command.CommandTimeout.
DI>Ну да, но когда мы передаем текст и получаем только результат — доступ к Command мы не имеем...
Не имеем, надо сделать чтобы имели.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, gloomy rocker, Вы писали: GR>Понятно... GR>А какова общая концепция, и что эта штука будет уметь?
И много-много денюшков детишкам принесла...
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Igor Trofimov, Вы писали:
iT>А как бы мне заставить dbManager работать с адаптерами, указвая им мои собственные DataTableMappings ?
iT>Что-то вроде ExecuteDataTable(sqlText, dataTable, dataTableMapping, params parameters) хочется.
А что такое dataTableMapping? IDictionary?
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Игорь Ткачёв, Вы писали:
ИТ>Аннотация: ИТ>В статье подробно рассматривается состав и способы применения пространства имён Rsdn.Framework.Data, представляющего собой высокоуровневую обёртку над ADO.NET.
в рамках б-бы за повышение документированности неплохо бы статейку актуализировать, ибо как стартап к системе она очень ценная, юнит тесты, конечно, источник знаний, но явно не дают быстрого и простого понимания что к чему
да и ссылки неактуальные, ниткой выше люди жалуются... це бардак =)
Здравствуйте, ili, Вы писали:
ili>в рамках б-бы за повышение документированности неплохо бы статейку актуализировать, ибо как стартап к системе она очень ценная, юнит тесты, конечно, источник знаний, но явно не дают быстрого и простого понимания что к чему
помятуя о занятости основных игроков, решил помочь с этим делом здесь "рыба" (писата в соотв-ии с требованиями к оформлению статей).
основана на изначалной статье, на сей момент дописата вплоть до методов Execute, что дальше, там накидан небольшой план.
если це устраивает — готов продолжить, если це не устраивает — хозяин барин, если це устраивает частично — давайте ЦУ.
Здравствуйте, ili, Вы писали:
ili>основана на изначалной статье, на сей момент дописата вплоть до методов Execute, что дальше, там накидан небольшой план. ili>если це устраивает — готов продолжить, если це не устраивает — хозяин барин, если це устраивает частично — давайте ЦУ.
там в доке, в самом конце там где про ExecuteDictionary есть одна маленькая непонятка... можно мне словами разъяснить что и как там получается на счет "ID" и "@PersonId" выступающих как ключи...
честно говоря, тут некоторый бардак (ну у мя в голове — точно )...
т.к. в ряде случаев я точно натыкался на эксепшн который говорил, что необходимо использовать имя для отображения (вроде это было в ExecuteResultSets) а тут ни ясно как так....
Если не указано '@', то значение берётся из поля уже смапленного объекта, если '@' присутсвует, то из исходной запсиси.
Зачем это надо. Первый случай может пригодиться, если словарь строится по полю, которое явно не отображается на исходную запись. Например, какое-нибудь составное поле в объекте. Второй случай может понадобиться, когда нужно построить словарь по полю, которое есть в исходном рекордсете, но не отображается на объект. Если ключевое поле один в один отображается на объект, то разницы нет.
... << RSDN@Home 1.2.0 alpha rev. 771>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, ili, Вы писали:
IT>Примерно из той же серии: http://www.bltoolkit.net/Doc/DataAccess/ExecuteDictionary.htm
IT>Если не указано '@', то значение берётся из поля уже смапленного объекта, если '@' присутсвует, то из исходной запсиси. IT>Зачем это надо. Первый случай может пригодиться, если словарь строится по полю, которое явно не отображается на исходную запись. Например, какое-нибудь составное поле в объекте. Второй случай может понадобиться, когда нужно построить словарь по полю, которое есть в исходном рекордсете, но не отображается на объект. Если ключевое поле один в один отображается на объект, то разницы нет.
а мы говорим именно о "собачке" или это зависит от DataProvider-а?
Здравствуйте, IT, Вы писали:
IT>Если не указано '@', то значение берётся из поля уже смапленного объекта, если '@' присутсвует, то из исходной запсиси. IT>Зачем это надо. Первый случай может пригодиться, если словарь строится по полю, которое явно не отображается на исходную запись. Например, какое-нибудь составное поле в объекте. Второй случай может понадобиться, когда нужно построить словарь по полю, которое есть в исходном рекордсете, но не отображается на объект. Если ключевое поле один в один отображается на объект, то разницы нет.
а при ExecuteResultSet возникает вот такое исключение:
HowTo.Data.ComplexMapping.Test : BLToolkit.Mapping.MappingException : Wrong mapping field name: 'ID', type: 'Parent'. Use field name 'ParentID' instead.
от того, что сначала происходит создание всех объектов и потом выполняется уже расстановка отношений?
вообще, хорошо бы к ObjectMapper-у добавить что-то вроде GetAlias(string originalName) (GetMapName(string originalName)) т.к. эти самые алиасы могут изменяться в рантайме путем XML extension (если такое есть, то я чо-та не нашел....).
Здравствуйте, ili, Вы писали:
ili>основана на изначалной статье, на сей момент дописата вплоть до методов Execute, что дальше, там накидан небольшой план. ili>если це устраивает — готов продолжить, если це не устраивает — хозяин барин, если це устраивает частично — давайте ЦУ.
Точно. Надо в итоге написать коллективными усилиями книжку и издать ее
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
Здравствуйте, ili, Вы писали:
ili>если це устраивает — готов продолжить, если це не устраивает — хозяин барин, если це устраивает частично — давайте ЦУ.
до понедельника планирую закончить про маппинг, если смогу, то и с датааксессом разберусь, но не факт.
потом в отпуск — на экскурсии по питейным заведениям питера.
из того что еще необходимо описать:
EditableObjects — способы подачи блюда под различными соусами. кстати на EditableXmlDocument вообще никакого компромата нет, ни адресов, ни паролей, ни явок.
Validation — охотник и заяц, кто прав, кто не прав.
Reflection & TypeBuilder — точно нужно, но моего кунг-фу не хватит.
Aspects (хотя, они достаточно подробно в справке описаны...)
Здравствуйте, ili, Вы писали:
ili>>в рамках б-бы за повышение документированности неплохо бы статейку актуализировать, ибо как стартап к системе она очень ценная, юнит тесты, конечно, источник знаний, но явно не дают быстрого и простого понимания что к чему
ili>помятуя о занятости основных игроков, решил помочь с этим делом здесь "рыба" (писата в соотв-ии с требованиями к оформлению статей).
По мне так лучше писать в wiki (http://projects.rsdn.ru/RFD) — больше вероятность что основные игроки поправят на ходу
А потом можно уже будет и в doce оформить, для публикации на сайте.
Здравствуйте, der Igel, Вы писали:
DI>По мне так лучше писать в wiki (http://projects.rsdn.ru/RFD) — больше вероятность что основные игроки поправят на ходу DI>А потом можно уже будет и в doce оформить, для публикации на сайте.
гут )
но, лично мне, проще сначала написать доку, а потом ее при необходимости, расковеркать как угодно
Здравствуйте, ili, Вы писали:
DI>>По мне так лучше писать в wiki (http://projects.rsdn.ru/RFD) — больше вероятность что основные игроки поправят на ходу DI>>А потом можно уже будет и в doce оформить, для публикации на сайте. ili>гут ) ili>но, лично мне, проще сначала написать доку, а потом ее при необходимости, расковеркать как угодно
вставил бы ты в самом деле текущую версию в wiki, а то периодически возникает желание пофиксить непонятки текущей документации, а негде
Здравствуйте, Odi$$ey, Вы писали:
OE>вставил бы ты в самом деле текущую версию в wiki, а то периодически возникает желание пофиксить непонятки текущей документации, а негде
внемени нет
некогда толком даже дописать то что начал.
от того, что было раньше добавлено про маппинг, плюс описание атрибутов.
нету описания XML расширений и DataAccess-а