Mapping enum with fluent nhibernate

后端 未结 3 707
盖世英雄少女心
盖世英雄少女心 2020-12-14 06:42

I am following the http://wiki.fluentnhibernate.org/Getting_started tutorial to create my first NHibernate project with Fluent NHibernate

I have 2 tables

1)

相关标签:
3条回答
  • 2020-12-14 07:08
    public class Account {
        public virtual int Id {get; private set;}
        public virtual string AccountHolderName {get; set;}
        public virtual AccountType AccountType {get; set;}
    }
    
    public AgencyMap() {
        Id(o => o.Id);
        Map(o => o.AccountHolderName);
        Map(o => o.AccountType);
    }
    

    Fluent NHibernate saves enum values as string by default if you want to override that you need to supply a convention for it. Something like:

    public class EnumConvention :
        IPropertyConvention, 
        IPropertyConventionAcceptance
    {
        #region IPropertyConvention Members
    
        public void Apply(IPropertyInstance instance)
        {
            instance.CustomType(instance.Property.PropertyType);
        }
    
        #endregion
    
        #region IPropertyConventionAcceptance Members
    
        public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
        {
            criteria.Expect(x => x.Property.PropertyType.IsEnum ||
            (x.Property.PropertyType.IsGenericType && 
             x.Property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) &&
             x.Property.PropertyType.GetGenericArguments()[0].IsEnum)
            );
        }
    
        #endregion
    }
    

    Almost forgot that you need to add the convention to your fluent config as well. You do that at the same place you add the mappings:

    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<BillingRecordMap>()
    .Conventions.AddFromAssemblyOf<EnumConvention>()
    
    0 讨论(0)
  • 2020-12-14 07:09

    A Great way to do this, is implement the interface IUserType and Create a CustomType with the rules to write and read, that´s a example to boolean:

     public class CharToBoolean : IUserType
    {
        public SqlType[] SqlTypes => new[] { NHibernateUtil.String.SqlType };
    
        public Type ReturnedType => typeof(bool);
    
        public bool IsMutable =>true;
    
        public object Assemble(object cached, object owner)
        {
            return (cached);
        }
    
        public object DeepCopy(object value)
        {
            return (value);
        }
    
        public object Disassemble(object value)
        {
            return (value);
        }
    
        public new bool Equals(object x, object y)
        {
            if (ReferenceEquals(x, y)) return true;
    
            var firstObject = x as string;
            var secondObject = y as string;
    
            if (string.IsNullOrEmpty(firstObject) || string.IsNullOrEmpty(secondObject)) return false;
    
            if (firstObject == secondObject) return true;
            return false;
        }
    
        public int GetHashCode(object x)
        {
            return ((x != null) ? x.GetHashCode() : 0);
        }
    
        public object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            var obj = NHibernateUtil.String.NullSafeGet(rs, names[0]);
    
            if (obj == null) return null;
    
            var value = (string)obj;
    
            return value.ToBoolean();
        }
    
        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            if(value != null)
            {
                if ((bool)value)
                {
                    ((IDataParameter)cmd.Parameters[index]).Value = "S";
                }
                else
                {
                    ((IDataParameter)cmd.Parameters[index]).Value = "N";
                }
            }
            else
            {
                ((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value;
            }
        }
        public object Replace(object original, object target, object owner)
        {
            return original;
        }
    }
    

    }

    the mapping:

      this.Map(x => x.DominioGenerico).Column("fldominiogen").CustomType<CharToBoolean>();
    

    It´s a sample but you can do this with other types.

    0 讨论(0)
  • 2020-12-14 07:14

    The following apparently no longer works https://stackoverflow.com/a/503327/189412

    How about just doing this:

    public AgencyMap() {
        Id(o => o.Id);
        Map(o => o.AccountHolderName);
        Map(o => o.AccountType).CustomType<AccountType>();
    }
    

    The custom type handles everything :)

    0 讨论(0)
提交回复
热议问题