代码之家  ›  专栏  ›  技术社区  ›  James Allen

NHibernate中的空值对象

  •  10
  • James Allen  · 技术社区  · 17 年前

    我有一个person实体,其中包含一个地址作为值对象:

    public Person()
    {
        WithTable("Person");
        Id(x => x.Id);
        Component<Address>(x => x.Address, a =>
        {
            a.Map(x => x.Address1);
            a.Map(x => x.Address2);
            a.Map(x => x.Address3);
            a.Map(x => x.Town);
            a.Map(x => x.Postcode);
        });
    }
    

    它在NHibernate文档中声明,如果值对象(Address1、Address2等)的所有属性都为null,则整个组件将映射为null(即Person.Address为null)。在所有地址字段都为空的情况下,这会给我带来问题,因为在我的页面中,我可能有(我正在进行ASP MVC):

    <%= Html.TextBoxFor((x => x.Address.Address1))%>
    

    这会因空引用异常而中断。因此,我正在寻找一种干净的方法,将Address设置为一个新的Address()对象,而不是当我从数据库中加载一个人时,如果所有字段都为空,则不需要手动执行该操作。我已经打消了以下想法:

    在我的视图中执行空检查(yuk,可怕)

    使数据库字段不可为空(我正在处理遗留数据库)

    有人有什么想法吗?

    3 回复  |  直到 17 年前
        1
  •  5
  •   James Allen    17 年前

    由于James的想法(参见他的回答和评论),我已将我的个人实体的Address属性修改为:

    public virtual string Address { get; set; }
    

    致:

    private Address _address;
    public virtual Address Address
    {
        get { return _address ?? new Address(); }
        set { _address = value; }
    }
    

        2
  •  2
  •   James Gregory    17 年前

    我没有任何明确的答案来创建一个未映射的方法/属性访问器,如果实际地址为null,它将返回一个默认的/null对象。

    public Address GetAddressOrDefault()
    {
      return Address ?? new NullAddress();
    }
    

    或者与第一个类似,为您的 Address 您在视图中使用的。

    public class AddressViewData
    {
      private Address address;
    
      public AddressViewData(Address address)
      {
        this.address = address ?? new NullAddress();
      }
    
      // expose all address properties as pass-throughs
      public string Street
      {
        get { return address.Street; }
      }
    }
    
        3
  •  0
  •   Stefan Steinegger    15 年前

    在某些情况下,编写NHibernate自定义类型非常容易。它将返回null对象,而不是将组件设置为null。我在某些情况下这样做了,然后你可以忘记空值。

    Example of a composite user type