Remoting вопрос об архитектуре решения
От: Nixon Россия  
Дата: 18.12.07 11:35
Оценка:
VS 2005, Framework 2.0

Работаю над двузвенной СУБД

Общее решение выглядит примерно так:
Client клиентская компонента (WindowsApplication, формы, сериализуемые объекты которыми оперирует приложение)
DAL — data access logic серверная компонента (WindowsService, имеет доступ к БД, возвращает клиенту полученные из БД сериализуемые объекты)
MS SQL (собственно БД)

Сериализуемый объект (СО) это набор скалярных полей и таблиц
class serObj
{
int ID;
string name;
...
DataTable Moves;
...
}

DAL реадизует интерфейс через который к нему обращается клиент
class DAL:MarshalByRef, IDAL
{
void Read(ref serObj)
{serObj.Moves = sql.ReadMove(....); serObj.Moves.Constraints.Add(new UniqueConstraint(...)); ...}
}




На таблицы содержащиеся в СО, наложены ограничения. Так как клиент "тонкий", то вся логика работы с СО заложена в DAL, в том числе и ограничения.
Если в БД все хорошо, то клиент получает готовую, заполненную таблицу с ограничениями и работает с ней не нарушая логики организации данных.

Плохо становится когда в БД, содержаться записи не удовлетворяющие этим ограничениям (в моем случае при переносе из другой БД).
В моем случае ситуация развивалась так:

DAL получает таблицу с ошибочными сведениями и пытается прикрутить к ней constraint (например UniqueConstraint), возникает исключение, если его обработать и все таки вернуть таблицу клиенту, то исключение тут же возникает в клиенте, при этом исключение не содержит никакой полезной информации об ограничении.

Повозился с Contsraint и DataTable, и понял что при такой схеме либо придется возвращать данные без ограничения (т.е их вряд ли исправят), либо возвращать неполные\пустые, но с ограничением.

Подумал и переделал DAL следующим образом добавил событие которое отправляется в догонку данным и служит сигналом о том что данные не удовлетворяют наложенным сервером ограничениям и их необходимо исправить.
class DAL:MarshalByRef, IDAL
{
event NeedConstraintHandler NeedConstraint;

void Read(ref serObj)
{
   serObj.Moves = sql.ReadMove(....); 
   try { serObj.Moves.Constraints.Add(new UniqueConstraint(...)); } 
   catch (Exception exc) {NeedConstraint(NeedConstraintEventArgs args); }
   ...
}


Когда переделал понял, что событие происходит раньше чем возвращаются сами данные.
Т.е СО еще в обработке, а клиент уже получил сигнал о том, что он (СО) неверен.
Эту ситуацию конечно можно разрешить, генерирую событие из отдельного потока и синхронировав этот поток с потоком обрабатывающим СО.

Оглядел все свое "творчество" и понял, что решение сложное и интуитивно мне кажется неоправданно сложное. Мне кажется, что где-то я прокололся и все должно решаться проще. А вот как понять не могу.

Собственно вопрос: Как организовать обмен DataTable с ограничениями между двумя удаленными компонентами, таким образом чтобы они могли обмениваться данными которые не удовлетворяют этим ограничениям?

PS Есть конечно вариант создать для каждого поля-таблицы вспомогательное поле содеражащее исходные данные для ограничения
(само ограничение по-моему не сериализуемо) и собирать и прикручивать на клиенте. НО во первых это требует жесткого контроля за кодом, т.е после каждого обращения к DAL, необходимо проверить не надо ли чего прикрутить к полученным таблицам. Второе НО субъективное на мой взгляд этот вариант не очень клиентский, не очень "тонкий клиент" получается.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.