Контракт WCF для обновления на уровне поля - PullRequest
4 голосов
/ 22 января 2010

Я разрабатываю приложение, которое выполняет некоторые операции CRUD через службу WCF.Метод read возвращает полную сущность, обновление выполняется через унаследованную систему, и обновлять должны только измененные значения.

Каков наилучший способ разработки контракта данных для этого сценария без простой отправки словаряпар ключ-значение?

Ответы [ 7 ]

1 голос
/ 22 января 2010

Единственное, о чем я могу думать, это сделать ваш компонент долговечным - т.е. сохранить его состояние в файле или базе данных. Таким образом, в обновлении вы можете сравнить предыдущее состояние с передаваемым состоянием. Я не уверен, что это хороший путь, поскольку он принесет больше издержек, чем просто передача пар ключ-значение.

Со стороны это может выглядеть более ЧУВСТВЕННО или что-то в этом роде, но с практической точки зрения вам может быть лучше просто передать некоторые указания относительно того, какие значения изменились.

1 голос
/ 28 сентября 2011

Если это поможет, не уверен точно, что ты ищешь, хотя ...

В запросе на обновление действуют только те поля, которые не равны нулю.

Кроме того, оберните все типы, которые не допускают обнуление, в структуру, обнуляемую.

Как пример ...

Update( Nullable<int> orderNumber, 
        Nullable<DateTime> orderDate, 
        Nullable<bool> isComplete )
{
    if( orderNumber != null )
        databaseRecord.OrderNumber = orderNumber;

    if( orderDate != null )
       databaseRecord.OrderDate = orderDate;

    if( isComplete != null )
       databaseRecord.IsComplete = isComplete;
}
0 голосов
/ 05 февраля 2010

Рассматривая ваши требования и заявления, я сделал несколько предположений, прежде чем начать писать свое видение возможного решения:

  • Вы используете один и тот же класс для извлечения (тип возвращаемого значения операции «чтение») и обновления элемента (тип входного параметра операции «обновление») в службе WCF.
  • Ваша текущая проблема реализации заключается в том, как использовать исходный класс (не словарь) И все же иметь возможность определять «что изменилось по сравнению с чтением», когда вы получаете операцию «Обновление», вызываемую в вашей службе WCF
  • Вы пишете как сервер, так и клиент. Оба написаны с использованием MS .Net Framework.

Если это так, проблема заключается в отсутствии информации о методе обновления. Требуемая информация «изменилась», что может быть выведено, если присутствует 2-е состояние для сравнения или оно уже должно присутствовать рядом с состоянием, которое необходимо обновить в серверной части.

Поскольку у вас есть только «внутреннее состояние» (без флагов), когда клиент отправляет свои данные в службу WCF, как нам определить, что изменилось? Очевидно, что мы хотим предотвратить повторное чтение, чтобы получить текущее состояние сервера и начать сравнение.

Отправка исходного и измененного состояния с клиента на сервер является возможным, но сложным решением. Кроме того, клиент не заинтересован в этой информации, сервер.

Сложив все это, я полагаю, что изменение типа входного параметра операции «Обновить» - самый простой способ. Создайте класс декоратора, который добавляет поведение «грязного бита» к исходной сущности. Используйте этот новый класс в качестве входного параметра для операции «Обновление». После этого у вас будет возможность проверить этот грязный бит рядом с полным состоянием, отправленным клиентом. Основное изменение на стороне клиента заключается в том, что объект, необходимый для операции «Обновление», больше не совпадает с объектом, предоставленным методом «Чтение». Чтобы облегчить эту боль, я бы, вероятно, создал класс декоратора, который добавил необходимую обработку «грязного бита». Это требует только изменения экземпляра объекта при сохранении подписи интерфейса для клиента (очень мало изменений кода).

0 голосов
/ 04 февраля 2010

Вы можете оставить договор на передачу данных в одиночку и обновить договор на обслуживание. Просто представьте обязательные поля для метода как свойства в контракте на обслуживание. Любое приложение-потребитель, использующее службу, должно быть обновлено, если контакт службы изменился, но приложение-потребитель будет знать, что требуется для успешного обновления данных.

У этого метода есть свои плюсы и минусы, но я использую его, когда метод, который я пишу, не требует полного контракта данных.

- отредактировано для орфографической ошибки -

0 голосов
/ 02 февраля 2010

Вы можете использовать DataSet, чтобы сохранить ваши изменения. Назовите вашу запись как DataSet, затем присвойте ей некоторые значения. DataSet.Tables [0] .GetChanges () даст вам столбцы, которые были изменены.

0 голосов
/ 24 января 2010

У меня было две идеи о том, как этого добиться:

  1. Если клиент отправит как исходную, так и измененную сущность в полном объеме, служба затем выяснит, какие свойства былиизменено.

  2. Используйте шаблон, похожий на Nullable, давайте назовем его Modified с флагом IsModified и свойством NewValue типа T. Каждое свойство DataContract будет этого типа, службаможете проверить флаг IsModified при выполнении обновления.

У устаревшей системы, которую мы используем, есть API, который принимает String.Empty для идентификации неизмененных полей, '?'символ используется для обозначения обновления пустой строки.Мне действительно не нравится это, пользователь API вынужден читать документацию, и если вы действительно хотите сохранить «?»ты не можешьЯ хочу, чтобы наш API веб-сервиса был более явным.

0 голосов
/ 24 января 2010

лучший способ сделать это с помощью словаря свойств, просто представить ваши сущности как словарь имени и значения свойства. сохранить все изменения в некотором списке и передать частичный словарь со всеми измененными свойствами.

я думаю, что это лучший дизайн,

Если вы хотите избежать этого дизайна, отправьте всю сущность с некоторым списком измененных свойств. (чтобы сохранить транспорт, вы можете поставить ноль на другие свойства)

если вы не хотите изменять подпись контракта на обслуживание, вы можете вставить имена измененных свойств в заголовок

...