NHibernate 在拦截器中添加未映射的列 [英] NHibernate add unmapped column in interceptor

查看:40
本文介绍了NHibernate 在拦截器中添加未映射的列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to save a mapped entity using NHibernate but my insert to the database fails because the underlying table has a column that does not allow nulls and IS NOT mapped in my domain object. The reason it isn't mapped is because the column in question supports a legacy application and has no relevance to my application - so I'd like to not pollute my entity with the legacy property.

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

I know I could use a private field inside my class - but this still feels nasty to me. I've read that I can use an NHibernate interceptor and override the OnSave() method to add in the new column right before my entity is saved. This is proving difficult since I can't work out how to add an instance of Nhibernate.type.IType to the types parameter of my interceptor's OnSave.

我的实体大致如下:

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);
    }
}

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

Does anyone have any ideas on how to do this properly?

推荐答案

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

I can't say for sure since I've never actually done this (like Stefan, I also prefer to just add a private property), but can you just add a NHibernate.Type.BooleanType to the types array?

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

编辑

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

Yes, it looks like you are right; the types have an internal constructor. I did some digging and found TypeFactory:

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

Applications should use static methods and constants on NHibernate.NHibernateUtil if the default IType is good enough. For example, the TypeFactory should only be used when the String needs to have a length of 300 instead of 255. At this point NHibernate.String does not get you thecorrect IType. Instead use TypeFactory.GetString(300) and keep a local variable that holds a reference to the IType.

所以看起来你想要的是NHibernateUtil:

So it looks like what you want is NHibernateUtil:

提供对全部范围的访问NHibernate 内置类型.类型实例可用于绑定值来查询参数.还有工厂用于新的 Blob 和 Clob.

Provides access to the full range of NHibernate built-in types. IType instances may be used to bind values to query parameters. Also a factory for new Blobs and Clobs.

typeList.Add(NHibernateUtil.Boolean);

这篇关于NHibernate 在拦截器中添加未映射的列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆