Nhibernate实现类似 BeanPropertyRowMapper 的类型映射

来源:互联网 发布:rip软件是什么意思 编辑:程序博客网 时间:2024/05/17 00:07

Nhibernate 通过sql 查询映射到自定义类时要求,类名和sql语句完全匹配,有时候,数据库字段和属性确实不一样,比如加下划线区分的这种,为了适应情况,我实现了个接口类

来。


    /// <summary>
    /// 解决数据库字段与类属性大小写不一致问题
    /// </summary>
    public class BeanTransformerAdapter<T> : IResultTransformer
    {
        ILog log = LogManager.GetLogger(typeof(BeanTransformerAdapter<T>));
        public BeanTransformerAdapter(Type result)
        { }
        public BeanTransformerAdapter()
        {
            initialize(typeof(T));
        }
        public BeanTransformerAdapter(Type result, bool checkFullyPopulated):this(result)
        {
            this.checkFullyPopulated = checkFullyPopulated;
        }
        // protected readonly static Log  Logger= LogFactory.getLog(typeof(BeanTransformerAdapter));


        /** The class we are mapping to */
        private Type mappedClass;


        /** Whether we're strictly validating */
        private bool checkFullyPopulated = false;


        /** Whether we're defaulting primitives when mapping a null value */
        private bool primitivesDefaultedForNullValue = false;


        /** Map of the fields we provide mapping for */
        private Dictionary<String, PropertyInfo> mappedFields;


        /** Set of bean properties we provide mapping for */
        private HashSet<String> mappedProperties;


        protected void initialize(Type mappedClass)
        {
            this.mappedClass = mappedClass;
            this.mappedFields = new Dictionary<String, PropertyInfo>();
            this.mappedProperties = new HashSet<String>(); 
            PropertyInfo[] pds = mappedClass.GetProperties().Where(p => p.GetMethod.IsVirtual).ToArray(); 
            foreach (PropertyInfo pd in pds)
            {
                //if (pd.getWriteMethod() != null)
                //{
                this.mappedFields.Add(pd.Name.ToLowerInvariant(), pd);
                String underscoredName = UnderscoreName(pd.Name);
                if (!pd.Name.ToUpperInvariant().Equals(underscoredName) && !string.IsNullOrEmpty(underscoredName))
                {
                    this.mappedFields.Add(underscoredName, pd);
                }
                this.mappedProperties.Add(pd.Name);
                //}
            }
        }
        private String UnderscoreName(String name)
        {
            if (!string.IsNullOrEmpty(name))
            {
                return "";
            }
            StringBuilder result = new StringBuilder();
            result.Append(name.Substring(0, 1).ToUpperInvariant());
            for (int i = 1; i < name.Length; i++)
            {
                String s = name.Substring(i, i + 1);
                String slc = s.ToLowerInvariant();
                if (!s.Equals(slc))
                {
                    result.Append("_").Append(slc);
                }
                else
                {
                    result.Append(s);
                }
            }
            return result.ToString();
        }
        //public IList TransformList(IList collection)
        //{
        //    throw new NotImplementedException();
        //}


        //public object TransformTuple(object[] tuple, string[] aliases)
        //{
        //    throw new NotImplementedException();
        //}
        private Type result;
        private List<PropertyInfo> properties = new List<PropertyInfo>();


        public IList TransformList(IList collection)
        {
            return collection;
        }
        public BeanTransformerAdapter(Type result, params string[] names)
        {
            this.result = result;
            foreach (string name in names)
            {
                properties.Add(result.GetProperty(name));
            }
        }


        public object TransformTuple(object[] tuple, string[] aliases)
        {
            //object instance = Activator.CreateInstance(result);
            //for (int i = 0; i < tuple.Length; i++)
            //{
            //    properties[i].SetValue(instance, tuple[i], null);
            //}
            //return instance;
            HashSet<String> populatedProperties = new HashSet<String>() ;
            Object mappedObject = Activator.CreateInstance<T> ();
               for (int i = 0; i < aliases.Length; i++)
            {
                String column = aliases[i];
                var pName = column.Replace("_", "").Replace(" ", "").ToLowerInvariant();
                if (!this.mappedFields.Keys.Contains(pName)) continue;
                PropertyInfo pd = this.mappedFields[pName];
                if (pd != null)
                {
                    try
                    {
                        Object value = tuple[i];
                        try
                        {
                            pd.SetValue(mappedObject, tuple[i], null);
                        }
                        catch (TypeMismatchException e)
                        {
                            if (value == null && primitivesDefaultedForNullValue)
                            {
                              
                                log.Debug("Intercepted TypeMismatchException for column " + column + " and column '"
     + column + "' with value " + value + " when setting property '" + pd.Name + "' of type " + pd.GetType()
    + " on object: " + mappedObject);
                            }
                            else
                            {
                                throw e;
                            }
                        }
                        if (populatedProperties != null)
                        {
                            populatedProperties.Add(pd.Name);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("Unable to map column " + column
    + " to property " + pd.Name, ex);
                    }
                }
            }


            if (populatedProperties != null && !populatedProperties.Equals(this.mappedProperties))
            {
                log.Info(@"Given ResultSet does not contain all fields "
                + "necessary to populate object of class [" + this.mappedClass + "]: " + this.mappedProperties);
                //匹配不上的暂时不处理
                //           throw new Exception("Given ResultSet does not contain all fields "
                //+ "necessary to populate object of class [" + this.mappedClass + "]: " + this.mappedProperties);
            }


            return mappedObject;
        }
    }

--------------------------------------------------------------------------------------

使用:



         var session = SessionFactory.OpenSession();
            var queryString = "select * from T"
            var rslt1 = session.CreateSQLQuery(queryString).SetString("Id", orderId).SetResultTransformer(new BeanTransformerAdapter<DaoModel.ProcessOrderModel>()).List<DaoModel.ProcessOrderModel>();
           



原创粉丝点击