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

我知道我可以在课堂上使用私人场地 - 但这对我来说仍然很难受。我读取我可以使用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);
    }
}

有没有人对如何正确地做到这一点有任何想法?

有帮助吗?

解决方案

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

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

修改

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

  

应用程序应使用静态   方法和常量   NHibernate.NHibernateUtil如果   默认的IType足够好了。例如,TypeFactory应该只   当String需要长度为300而不是255时使用。此时   NHibernate.String不能让你得到正确的IType。而是使用TypeFactory.GetString(300)并保持一个   保存对IType的引用的局部变量。

所以看起来你想要的是 NHibernateUtil

  

提供对全方位的访问权限   NHibernate内置类型。 ITYPE   实例可用于绑定值   查询参数。也是一家工厂   对于新的Blob和Clobs。

typeList.Add(NHibernateUtil.Boolean);

其他提示

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top