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