Модераторы: gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Организация БД 
:(
    Опции темы
Afrodiziac
  Дата 23.4.2008, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 13.5.2007

Репутация: нет
Всего: нет



Здравствуйте,

Проблема такая, есть Sql БД. В этой БД есть 9 различных таблиц: Users, Notifys, Events, Chanels,.... 
И есть Win приложение на C#.
Суть работы которого, брать запись (-си ?) из таблицы Notifys в которой есть поля с идентификаторами: Канала по которому будет отправляться сообщение, События с которым ассоциируется эта запись и Подписчик которому собираемся отправить. У Подписчика есть свои настройки.

Как (упрощенно) работает алгоритм отправки:
1. Вытаскиваем 1-у запись из таблицы Notifys.
2. Смотрим какому Подписчику оно принадлежит.
3. Вытаскиваем настройки Подписчика.
4. Смотрим по какому Каналу собираемся отправлять.
5. и т.д.

Как это выглядит на практике:
Код работы Рассыльщика
Код

      do
      {
        //Запрашиваем первое неотправленное оповещение
        DataRow row = DataManager.GetNOTSendNotify();

        //Проверяем есть ли результат
        if (row != null)
        {
          //Запоминаем Guid подписчика
          Guid IDUser = (Guid)row[4];

          //Запрашиваем настройки подписчика
          int interval = DataManager.GetUserInterval(IDUser);
          bool isRepeat = DataManager.GetUserIsRepeat(IDUser);
        }
      }
      while (!_exitEvent.WaitOne(0, false));


Код функции GetNOTSendNotify()
Код

      _dataAdapter.SelectCommand.CommandText = "SELECT TOP 1 * FROM TableNotifys WHERE [IsSend] = 'FALSE'";
      _table.Clear();
      _dataAdapter.Fill(_table);
      if (_table.Rows.Count == 1)
        return _table.Rows[0];
      else
        return null;  



Код запроса настройки пользователя
Код

      _dataAdapter.SelectCommand.CommandText = string.Format("SELECT * FROM TableUsers WHERE [IDUser] = {0}", IDUser);
      _table.Clear();
      _dataAdapter.Fill(_table);
      if (_table.Rows.Count == 1)
        return (bool)_table.Rows[0].ItemArray[0];
      else
        return null; 



Короче, доступ к данным ооочень муторный! К примеру из кода видно, что я с помощью одного адаптера и одной таблицы пытаюсь вытаскивать по чуть чуть (построчно) информацию из БД. А ведь мне нужно еще обратно, в БД, ложить обработанную информацию.

Возникают вопросы:
1. Сколько нужно адаптеров, таблиц дата сетов и т.п. для работы с одной БД?
2. Как организовать работу с кучей таблиц??

Неужели нужно для каждой таблицы заводить целый комплект Адаптер + КомандаSelect + КомандаInsert + КомандаDelete + ДатаСет ?? А если таблиц 50??

 

PM MAIL   Вверх
Afrodiziac
Дата 23.4.2008, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 13.5.2007

Репутация: нет
Всего: нет



"Наилучшим способом управления данными в цепочке "несколько объектов DataTable объекта DataSet - несколько таблиц в базе данных" является создание отдельных объектов DataAdapter для каждого экземпляра DataTable." (с) Intuit.ru

:( По моему ADO это одна большая какашка

Это сообщение отредактировал(а) Afrodiziac - 23.4.2008, 19:02
PM MAIL   Вверх
informatik
Дата 23.4.2008, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 4.11.2007

Репутация: 1
Всего: 6



Цитата

Неужели нужно для каждой таблицы заводить целый комплект Адаптер + КомандаSelect + КомандаInsert + КомандаDelete + ДатаСет ?? А если таблиц 50??


Интересный вопрос....

Ответ: ДА. 

А ты хочешь для всех таблиц иметь одну и ту же команду SELECT...  клас..... smile 
--------------------
namespace informatik
PM MAIL   Вверх
Afrodiziac
  Дата 24.4.2008, 07:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 13.5.2007

Репутация: нет
Всего: нет



Хорошо, пусть я создал кучу адаптеров

Код

    protected SqlDataAdapter _daTableNotifys;
    protected SqlDataAdapter _daTableUsers;
    protected SqlDataAdapter _daTableGlobalProperties;
    protected SqlDataAdapter _daTableChanels;
    protected SqlDataAdapter _daTableEvents;
    protected SqlDataAdapter _daTableUsersChanels;
    protected SqlDataAdapter _daTableEventsFiles;
    protected SqlDataAdapter _daTableFiles;
    protected SqlDataAdapter _daTableChanelsProperties;
    protected DataSet _ds;


подготовил датасет

Код

        _ds = new DataSet();
        _ds.Tables.Add(new DataTable("TableNotifys"));
        _ds.Tables.Add(new DataTable("TableUsers"));
        _ds.Tables.Add(new DataTable("TableGlobalProperties"));
        _ds.Tables.Add(new DataTable("TableChanels"));
        _ds.Tables.Add(new DataTable("TableEvents"));
        _ds.Tables.Add(new DataTable("TableUsersChanels"));
        _ds.Tables.Add(new DataTable("TableEventsFiles"));
        _ds.Tables.Add(new DataTable("TableFiles"));
        _ds.Tables.Add(new DataTable("TableChanelsProperties"));


и сделал общую функцию инициализации адаптера

Код

    private void InitAdapter(ref SqlDataAdapter adapter, ref SqlConnection con, string select)
    {
      //Создаем адаптер
      adapter = new SqlDataAdapter(select, con);
      adapter.SelectCommand.CommandText = select;
      adapter.SelectCommand.CommandType = CommandType.Text;

      //Создаем строителя команд
      SqlCommandBuilder builder = new SqlCommandBuilder(adapter);

      adapter.InsertCommand = builder.GetInsertCommand(true);
      adapter.InsertCommand.CommandType = CommandType.Text;

      adapter.UpdateCommand = builder.GetUpdateCommand(true);
      adapter.UpdateCommand.CommandType = CommandType.Text;

      adapter.DeleteCommand = builder.GetDeleteCommand(true);
      adapter.DeleteCommand.CommandType = CommandType.Text;
    }


к примеру вызываем ее так
Код

      InitAdapter(ref _daTableNotifys, ref _con, "SELECT * FROM TableNotifys");


А если мне понадобится сделать какой-то специфический запрос к таблице TableNotifys, я же не смогу использовать соответствующий адаптер _daTableNotifys? в том плане, что _daTableNotifys.SelectCommand.CommandText придется изменять...

Добавлено через 8 минут и 40 секунд
Пока что решение такое. 

1. Из БД забираю данные с помощью такой процедуры
Код

   SqlCommand command = new SqlCommand(Query, con);
   SqlDataReader reader = command.ExecuteReader();
   ...
   //Используем ридер
   ...


2. Узнав всю необходимую информацию, такую как ID, мы можем сохранять изменения в БД.
Код

  //На основе данныз ридера изменяем соответсвующие строки в датасет
  ds.Tables["Table"]. ...
  
  //Созраняем в БД
  adapter.Update(ds);


Гууд?
PM MAIL   Вверх
akizelokro
Дата 24.4.2008, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Крокодил
**


Профиль
Группа: Участник
Сообщений: 761
Регистрация: 30.7.2007

Репутация: нет
Всего: 5



Залезь в редактирование схемы, нажми по правой кнопке "Add->TableAdapter" (или "Add->Query", не помню точно, как делается), отредактируй у него "SelectCommand" (сообразно логике задачи, возможно указание параметров еще на стадии проектирования, количество таблиц из физической БД практически не ограничено), перепиши InsertCommand, UpdateCommand и deleteCommand (по необходимости, могут быть как простые запросы, так и встроенные процедуры, параметры возможны), а затем юзай как тебе заблагорассудится, но в стандартной манере.

Цитата

Неужели нужно для каждой таблицы заводить целый комплект Адаптер + КомандаSelect + КомандаInsert + КомандаDelete

необязательно. Если логика таблиц на уровне приложения не требует изменения таблицы БД, то Insert и Delete....
если таблица мусор или не нуждается в конкретном отдельном присутствии в датасете, то...

Цитата

"Наилучшим способом управления данными в цепочке "несколько объектов DataTable объекта DataSet - несколько таблиц в базе данных" является создание отдельных объектов DataAdapter для каждого экземпляра DataTable." (с) Intuit.ru

Лучшее - враг хорошего. Если на клетке со слоном написано крокодил, не верь глазам своим.


--------------------
a = a + b; b = a - b; a = a - b;
PM MAIL   Вверх
jonie
Дата 24.4.2008, 22:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 8
Всего: 118



а я б сделал хранимку на базе и не парился бы (и модификация базы проще и гемора меньше).
ну и соотвественно дергал бы ее....
еще вариант сделать View в базе чтобы сразу брать с него данные (в том виде которй вам уже нужен).
+для view можно будет сделать индекс (+к производительности, -к простоте изменения структуры базы).

кстати, view можно сделать очень хитрый... например завести стец табличку где хранить дату последней отсылки сообщений, а view строить по усливию where LastSentDateTime<row.updated
....

да вариантов тьма... все зависит от того что вам надо : мленькая база или высокая производительность на выборку....

Это сообщение отредактировал(а) jonie - 24.4.2008, 22:50


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
stab
mr.DUDA
Exception

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, stab, mr.DUDA, Exception.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Базы данных под .NET | Следующая тема »


 




[ Время генерации скрипта: 0.1298 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.