空值与未设置值

时间:2009-05-11 07:37:02

标签: wcf design-patterns datacontract

我们编写了一个Web服务,它使用一个简单的实体转换器将DTO的值映射回“真正的”服务器端业务对象。作为这个练习的一部分。我们在明确设置空值未设置值的客户端之间遇到了“有趣”的区别。

问题本质上是我们想要在真实业务对象上设置默认值,如果客户端没有明确设置值,但是使用标准的可空类型则无法判断是否存在客户明确表示“将此设置为空”或者只是不设置它。

这里的解决方案显然是某种“旗帜”。

在业务对象中,我们可以使用属性设置器中设置的私有“IsDirty”标志在内部跟踪字段的状态,但是DTO只是真正指定了接口,因此这意味着将此数据公开给公众。这留下了许多实现选项。语言是C#(如此静态类型)所以......

  1. 我们可以在每个属性上公开一个“IsSet”标志吗?
  2. 我们可以将每个属性公开为具有.Value和.IsSet属性的类吗? 等等。
  3. 如何选择在数据合约上公开这些“标志”? 你认为这是什么最好的做法?

    对此的任何意见将不胜感激。

4 个答案:

答案 0 :(得分:3)

为每个属性值使用一个类将更具可伸缩性,必须为每个属性声明一个bool。它还可以让您选择哪些属性可以保留为空和/或设置为空。

答案 1 :(得分: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的引用仍然可以为null,您需要在构造函数中创建它们。并且很难使值只能在内部访问或受到保护。


就个人而言,我会尽量避免这个问题。为什么“未定义”确实存在?你是在发送差异,不完整的Dtos,或者它来自哪里?此问题可能来自过滤器,如果您将字段过滤为null或者根本不过滤它,则需要区别。但是对于这种情况,无论如何你都需要一个特殊的“场过滤器”类。

答案 2 :(得分:1)

一般来说,你在这里谈论的是一个默认值,它与用户可以设置的任何值都不同。所以只需指定;将默认值设置为不在用户可以设置的允许值范围内的值。这样,如果该值是默认值,则表示尚未设置;如果值不是那个,你知道用户已经修改了它。仅仅因为其中一个用户可设置的值为null似乎就是在抛弃你;只是将它视为用户可设置值集之一;将变量的整个范围设置为略大的一组,并带有一个额外的默认值。这应该可以解决你的问题。

答案 3 :(得分:0)

之前我遇到过这个问题。您可以通过在构建DTO时引入一些默认值来解决这个问题,但这并不理想。我已经更详细地发布了博客here,它可能有助于有人进一步了解这个问题。