1

我正在尝试使用 NHibernate 保存映射的实体,但我对数据库的插入失败,因为基础表的列不允许空值并且未映射到我的域对象中。它没有被映射的原因是因为有问题的列支持遗留应用程序并且与我的应用程序无关 - 所以我不想用遗留属性污染我的实体。

我知道我可以在课堂上使用私有字段 - 但这对我来说仍然令人讨厌。我读过我可以使用 NHibernate 拦截器并覆盖 OnSave() 方法以在保存我的实体之前添加到新列中。事实证明这很困难,因为我不知道如何将 Nhibernate.type.IType 的实例添加到我的拦截器 OnSave 的 types 参数中。

我的实体大致如下所示:

public class Client
{
    public virtual int Id { get; set; }
    public virtual int ParentId { get; set; }
    public virtual string Name { get; set; }
    public virtual string Phone { get; set; }
    public virtual string Email { get; set; }
    public virtual string Url { get; set; }
}

还有我的拦截器

 public class ClientInterceptor : EmptyInterceptor
{

    public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
    {
        if (entity is Client)
        {
            /*
              manually add the COM_HOLD column to the Client entity
            */
            List<string> pn_list = propertyNames.ToList();
            pn_list.Add("COM_HOLD");
            propertyNames = pn_list.ToArray();

            List<Object> _state = state.ToList();
            _state.Add(false);
            state = _state.ToArray();

            //somehow add an IType to types param ??

         }
         return base.OnSave(entity, id, state, propertyNames, types);
    }
}

有人对如何正确执行此操作有任何想法吗?

4

2 回答 2

1

就个人而言,我不会做这么复杂的。我会添加私有属性并为其分配一个默认值 - 完成。您还可以考虑数据库中的默认值,然后您无需执行任何其他操作。

private virtual bool COM_HOLD 
{ 
  get { return false; } 
  set { /* make NH happy */ } 
}

在为此编写拦截器之前,我会考虑编写一个数据库触发器。因为使用拦截器,您正在“污染”您的数据访问层。它可能会使其不稳定,并且您可能会遇到奇怪的问题。

于 2009-05-05T11:12:34.893 回答
1

我不能肯定地说,因为我从来没有真正这样做过(比如 Stefan,我也更喜欢只添加一个私有属性),但是你可以只添加一个NHibernate.Type.BooleanTypetypes数组中吗?

List<IType> typeList = types.ToList();
typeList.Add(new BooleanType());
types = typesList.ToArray();

编辑

是的,看起来你是对的;这些类型有一个internal构造函数。我做了一些挖掘,发现TypeFactory

如果默认的 IType 足够好,应用程序应该在 NHibernate.NHibernateUtil 上使用静态方法和常量。例如,TypeFactory 应该仅在 String 需要长度为 300 而不是 255 时使用。此时 NHibernate.String 不会为您提供正确的 IType。而是使用 TypeFactory.GetString(300) 并保留一个包含对 IType 的引用的局部变量。

所以看起来你想要的是NHibernateUtil

提供对所有 NHibernate 内置类型的访问。IType 实例可用于将值绑定到查询参数。也是新 Blob 和 Clob 的工厂。

typeList.Add(NHibernateUtil.Boolean);
于 2009-05-05T16:11:02.927 回答