2009-05-11 3 views
5

Мы написали веб-службу, которая использует простой транслятор объекта для сопоставления значений DTO на «реальных» бизнес-объектах на стороне сервера. Как часть этого упражнения. Мы столкнулись с «интересным» различием между явно установленными нулевыми значениями и клиентами, имеющими не установлено значение.Null vs Значение не установлено

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

Решение здесь, очевидно, своего рода «флаг».

Внутри бизнес-объекта мы можем отслеживать состояние поля с использованием частных флагов IsDirty, установленных в установщиках свойств, но DTO действительно определяет интерфейс, поэтому это означает публикацию этих данных для общественности. Это оставляет ряд вариантов реализации. Язык C# (поэтому статически типизирован), поэтому ...

  1. Мы можем выставить флаг «IsSet» на каждом свойстве?
  2. Мы можем предоставить каждому свойству класс, обладающий свойством .Value и .IsSet? и т.д. и т.п.

Как бы вы решили выставить эти «флаги» по Договору данных? Что вы здесь считаете лучшей практикой для этого?

Любые мнения об этом были бы весьма признательны.

ответ

3

Использование класса для каждого значения свойства будет более масштабируемым, что должно объявить bool для каждого свойства. Это также позволит вам выбрать, какие свойства могут быть пустыми и/или установлены в нуль.

3

Вы могли бы написать класс, который оборачивает флаги с данными:

public class DtoData<T> 
{ 
    T data; 
    bool IsSet { get; private set; } 
    T Data 
    { 
    get { return data; } 
    set { data = value; IsSet = true; } 
    } 
} 


public class XyzDto 
{ 
    // only private setters, initialize in constructor 
    DtoData<int?> SomeInt { get; private set; } 
    DtoData<string> SomeString { get; private set; } 
} 

Это имеет некоторые недостатки, так. Например, все ваши данные обернуты ссылочным типом, поэтому ссылка на DtoData все равно может быть нулевой, вам нужно создать их в конструкторе. И трудно сделать ценности доступными только внутренними или защищенными.


Лично я постараюсь избежать этой проблемы. Почему «не определено» на самом деле существует? Вы отправляете различия, неполные Dtos или откуда они взялись? Эта проблема может возникнуть с фильтрами, где вам нужна разница, если вы отфильтровываете поле для нуля или вообще не фильтруете его. Но для таких сценариев в любом случае вам нужен специальный «полевой фильтр».

0

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

1

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

Смежные вопросы