在Nhibernate中使用枚举

我们会经常有这种需求:把一个字段映射成一个枚举。

于是Nhibernate提供了这种能力,在mapping中不指定type,让NH自己推断就好。于是今天收工(喂。。。

呃。。。继续说。印象中,按照上述方法,NH会往你的char或者varchar字段中存入枚举对应的int值。

于是客户不爽了,他们想看到一个更有意义的字符,甚至字符串。 还好NH提供了两个类:EnumCharType和EnumStringType。

首先来看映射字符的情况,使用EnumCharType<T>还是比较容易的,直接来看NH的Test工程中的例子,entity和枚举定义如下

ExpandedBlockStart.gif 代码
     public   class  EnumCharBaz
    {
        
private  Int32 id;
        
private  SampleCharEnum type;

        
public   virtual  Int32 Id
        {
            
get  {  return  id; }
            
set  { id  =  value; }
        }

        
public   virtual  SampleCharEnum Type
        {
            
get  {  return  type; }
            
set  { type  =  value; }
        }
    }

    
public   enum  SampleCharEnum
    {
        On 
=   ' N ' ,
        Off 
=   ' F ' ,
        Dimmed 
=   ' D '
    }

 

hbm则如下

ExpandedBlockStart.gif 代码
     < class  name ="EnumCharBaz"  table ="bc_ecfoobarbaz" >
        
< id  name ="Id" >
            
< generator  class ="assigned" />
        
</ id >
        
< property  name ="Type"  column ="type"  type ="NHibernate.Type.EnumCharType`1[[NHibernate.Test.TypesTest.SampleCharEnum, NHibernate.Test]], NHibernate" />
    
</ class >

 

让我们再一次的强烈谴责NH变态的泛型写法吧~~

再来看映射字符串,使用内建的EnumStringType<T>,也很轻松。依然来看NH中的Test例子

ExpandedBlockStart.gif 代码
    public class GenericEnumStringClass
    {
        public virtual int Id
        { 
            get;
            set;
        }

        public virtual SampleEnum EnumValue
        { 
            get;
            set;
        }
    }

    public enum SampleEnum
    {
        On,
        Off,
        Dimmed
    }

 

ExpandedBlockStart.gif 代码
     < class  name ="NHibernate.Test.TypesTest.GenericEnumStringClass, NHibernate.Test"  table ="bc_estr" >
        
< id  name ="Id"  column ="id" >
            
< generator  class ="assigned"   />
        
</ id >

        
< property  name ="EnumValue"  type ="NHibernate.Type.EnumStringType`1[[NHibernate.Test.TypesTest.SampleEnum, NHibernate.Test]], NHibernate"  column ="enumc" />
    
</ class >

 

结果上来说,NH是把你的枚举ToString之后存入了DB。

如果你想进一步定制枚举对应的String内容的话,可以继承EnumStringType。强烈不建议继承EnumStringType<T>,看看他的代码就知道他有多么废品

    [Serializable]
    
public   class  EnumStringType < T >  : EnumStringType
    {
        
public  EnumStringType() :  base ( typeof  (T)) {}
    }

 

这不是啥有用的活儿都没做么。。。

为了使用上的方便,我实现了这样一个基类

ExpandedBlockStart.gif 代码
     public   class  GenericEnumStringType < TEnum >  : EnumStringType  where  TEnum :  struct
    {
        
protected   static  IDictionary < TEnum,  string >  Dictionary {  get private   set ; }
        
static  GenericEnumStringType()
        {
            
if  ( ! typeof (TEnum).IsEnum)
            {
                
throw   new  ArgumentException( " TEnum is not enum type " typeof (TEnum).FullName);
            }
            Dictionary 
=   new  Dictionary < TEnum,  string > ();
        }

        
public  GenericEnumStringType()
            : 
base ( typeof (TEnum))
        {
            
// do nothing
        }

        
public   override   object  GetValue( object  code)
        {
            
if  ( 0   ==  Dictionary.Count)
            {
                
return   base .GetValue(code);
            }
            var @enum 
=  (TEnum)code;
            
if  (Dictionary.ContainsKey(@enum))
            {
                
return  Dictionary[@enum];
            }
            
throw   new  ArgumentException( " Cannot convert " , code.ToString());
        }

        
public   override   object  GetInstance( object  code)
        {
            
if  ( 0   ==  Dictionary.Count)
            {
                
return   base .GetInstance(code);
            }
            var str 
=  code.ToString();
            
if  (Dictionary.Values.Contains(str))
            {
                
return
                    Dictionary.Where(pair 
=>  pair.Value.Equals(str, StringComparison.OrdinalIgnoreCase)).Select(
                        pair 
=>  pair.Key).First();
            }
            
throw   new  ArgumentException( " Cannot convert " , str);
        }
    }

 

然后自定义枚举到字符串的类就简化成了这样

ExpandedBlockStart.gif 代码
     public   class  YNTypeStringType : GenericEnumStringType < YNType >
    {
        
static  YNTypeStringType()
        {
            Dictionary.Add(YNType.Yes, 
" Yes! " );
            Dictionary.Add(YNType.No, 
" No! " );
        }
    }

 

hbm也映射这个类就好了,也不用写泛型了:)

好,今天就到这里~ 

转载于:https://www.cnblogs.com/jiaxingseng/archive/2010/08/27/1810330.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值