четверг, 12 ноября 2009 г.

Утилита для создания ClickOnce приложения

Очень удобно использовать механизм развёртывания приложения ClickOnce.В VS достаточно нажатия одной кнопки, и получаешь полноценно приложение развёртывания, сразу из проекта. Трудности возникают, когда пытаешься развернуть модульное приложение с динамической загрузкой библиотек кода (например, SCSF), Механизм ClickOnce, встроенный в VS не справляется с подобной задачей.
Помочь с решением такой проблемы может утилита Mage. Но использовать её не слишком удобно.
Сам DotNet Framework предоставляет весь необходимый инструментарий, для работы с манифестами. И создать приложение, которое сможет "собирать" установщик ClickOnce достаточно просто. Явные преимущества очевидны:
  • не нужно возиться с командной строкой;
  • механизм создания полностью под вашим контролем;
  • можно применить любые настройки.
После некоторых сомнений я решил изобрести велосипед написать собственное приложение для создания ClickOnce приложений. На мой взгляд, получилось удобно.
Исходные коды см. тут

понедельник, 12 октября 2009 г.

AzMan и SQL Server

Пришлось настраивать хранилище AzMan на SQL Server. Долго не получалось без видимой причины.
Оказалось, что для работы необходимо включить протокол TCP/IP для сервера.

Ну и указать соответствующую строку подключения:

mssql://Driver={SQL Server};Server={localhost};Trusted_Connection={True}/[DataBaseName]/[Storage].

P.S. У нас произошли небольшие изменения и пришлось модифицировать подключение к AzMan с использованием встроенной SQL авторизации. Теперь всё выглядит вот так:

mssql://Driver=SQL Server;Server=localhost;Uid=[username]; pwd=[userpassword];/[DataBaseName]/[Storage]

Странно, но в сети не смог найти информацию о подобном типе подключения. Пришлось придумывать самостоятельно.

пятница, 4 сентября 2009 г.

Синхронизация источников данных, c#

Уже не первый раз за свою практику сталкиваюсь с необходимостью синхронизации таблиц данных, которые хранятся различным образом. Ну, например, основная база данных храниться в СУБД (MS SQL Server, FireBird и т.д.), а некие наборы данных приходят в виде XML файлов.

И так, задача. Данные хранимые в СУБД должны соответсвовать тем данным, которые "пришли" в XML.
Таблица в СУБД имеет структутру Customer(int code, nvarchar name).
Как поступают входны данные, нам собственно и не важно.


Попытка №1
Конечно же, была очень плохой. Я делал 2 прохода по таблицам:
1 проход: перебор записей исходной таблицы, поиск в внешнем наборе.
2 проход: перебор записей внешнего набора, поиск в исходной таблице.
Очень медленно. Лишние переборы.

Попытка №2
Пообщавшись с мировой мудростью, дела пошли лучше.
Условие работы метода - наличие у данных PrimaryKey.
Сортируем исходную таблицу и внешний набор по значению PK (в нашем случае Customer.Code)

//Создаём два индекса для перебора записей
int iNew = 0;
int iCurrent = 0;

//В цикле выбираем 2 записи из таблицы. Нам конечно нужны только их PK.
int newId = (int)newCustomers.Rows[iNew]["Code"];
int currentId = (int)currentCustomers.Rows[iCurrent]["Code"];

//Сравниваем значения PK.
switch(newId.CompareTo(curId))
{
//add new
case -1:  
          Customer customer = new Customer();
           customer.Code = newCustomers.Rows[iNew]["Code"];
           customer.Name = newCustomers.Rows[iNew]["Name"];
           InsertCustomer(customer);
           iNew++;
           break;
//update
case 0:
           currentCustomers.Rows[iCurrent]["Name"] = newCustomers.Rows[iNew]["Name"];
           iNew++;
           iCur++;
           break;
//delete
case 1:
           DeleteCustomer(currentCustomers.Rows[iCurrent]);
           iCur++;
           break;
}
Количество циклов N = newCustomers.Rows U currentCustomers.Rows
Методы InsertCustomer, DeleteCustomer - методы реализующие логику добавления и удаления записей, соответственно.