using System;
using System.Data;using System.Collections;using System.Collections.Generic;using System.Runtime.Remoting.Messaging;using System.Text.RegularExpressions;#if NHIBERNATE
//NHibernate Templateusing NHibernate;#endif#if ADO_NET
//Ado Templateusing Spring.Data.Core;using Spring.Data.Common;#endif//Query Info
using Framework.IDao;using Framework.Domain;using Framework;using Spring.Data;using Spring.Data.NHibernate.Generic;namespace Framework.Impl.Dao
{ public class ClassicDao : IClassicDao { #if NHIBERNATE private Spring.Data.NHibernate.HibernateTemplate hibernateTemplate; public Spring.Data.NHibernate.HibernateTemplate HibernateTemplate { get { return hibernateTemplate; } set { hibernateTemplate = value; } } private Spring.Context.IApplicationContext _ctx; protected Spring.Context.IApplicationContext ctx { get { if (_ctx == null) _ctx = Spring.Context.Support.ContextRegistry.GetContext(); return _ctx; } } public ISession session { get; set; } public Spring.Data.NHibernate.HibernateTemplate MHibernateTemplate { get { Spring.Data.NHibernate.HibernateTemplate _nContext = CallContext.GetData("NineskyContext") as Spring.Data.NHibernate.HibernateTemplate; if (_nContext == null) { _nContext = ctx["CHibernateTemplate"] as Spring.Data.NHibernate.HibernateTemplate; CallContext.SetData("NineskyContext", _nContext); } session = HibernateTemplate.SessionFactory.OpenSession(); return _nContext; }}
public object FindById(Type type, object id) { return MHibernateTemplate.Load(type, id); }public IList FindAll(Type type)
{ return MHibernateTemplate.LoadAll(type); } public object FindOne(QueryInfo info) { return MHibernateTemplate.Execute(delegate(ISession session1) { IQuery q = null; if (info.NamedQuery == null) { info.QueryObject = info.ToHQLString(); foreach (System.Collections.Generic.KeyValuePair<string, string> filter in info.Filters)//Enable Filter session.EnableFilter(filter.Value).SetParameter(filter.Key, info.Parameters[filter.Key]);q = session.CreateQuery(info.QueryObject + info.ToOrderBy());
} else q = session.GetNamedQuery(info.NamedQuery);SetParameters(q, info, MHibernateTemplate);
return q.UniqueResult();
}); }int CurrentCapacity = -1;
public IList FindList(QueryInfo info) { return (IList)MHibernateTemplate.Execute(delegate(ISession session1) { IQuery q = null; if (info.NamedQuery == null) { info.QueryObject = info.ToHQLString(); foreach (System.Collections.Generic.KeyValuePair<string, string> filter in info.Filters)//Enable Filter session.EnableFilter(filter.Value).SetParameter(filter.Key, info.Parameters[filter.Key]);q = session.CreateQuery(info.QueryObject + info.ToOrderBy());
} else q = session.GetNamedQuery(info.NamedQuery);SetParameters(q, info, MHibernateTemplate);
#region Check License Capacity
//if (CurrentCapacity == -1)//每次初始化运行 //{ // if (LicenseValidator.Capacity > 0) // { // int i = GetUserCount(); // if (i > LicenseValidator.Capacity + 1) // throw new UnauthorizedAccessException(string.Format("当前用户数'{0}'已超过授权最大用户数'{1}',系统已转为试用模式.\r\n请确认License文件有效,且正确放在bin目录.", i, LicenseValidator.Capacity)); // else // CurrentCapacity = i;//成功初始化 // } // else // CurrentCapacity = 0;//成功初始化 //} #endregionif (info.NamedQuery == null && info.TotalCount > 0)//进行分页过滤?
{ if (info.TotalCount == 1)//取总条数,分页 info.TotalCount = GetTotalCount(info); q.SetFirstResult(info.StartRecord); q.SetMaxResults(info.PageSize); } return q.List(); }); } public int GetTotalCount(QueryInfo info)//统计总条数 { long i = (long)MHibernateTemplate.Execute(delegate(ISession session1) { if (info.QueryObject == null) throw new ArgumentNullException("QueryObject", "info.QueryObject can't not be null in GetTotalCount."); if (info.QueryObject.IndexOf("from") < 0)//Get Count directly? info.QueryObject = info.ToHQLString();string sCountHQL = string.Format("SELECT COUNT({0}) {1}", info.CountField
, info.QueryObject.Substring(info.QueryObject.IndexOf("from")));//from ... if (info.Parameters.ContainsKey("NO_COUNT"))//分页时移除此条件、此参数 { sCountHQL = sCountHQL.Replace(info.Where["NO_COUNT"], string.Empty); info.Parameters.Remove("NO_COUNT"); } foreach (System.Collections.Generic.KeyValuePair<string, string> filter in info.Filters)//Enable Filter session.EnableFilter(filter.Value).SetParameter(filter.Key, info.Parameters[filter.Key]);IQuery q = session.CreateQuery(sCountHQL);
SetParameters(q, info, MHibernateTemplate);
q.SetResultTransformer(null);//Important return q.UniqueResult(); }); return Convert.ToInt32(i); }public static void SetParameters(IQuery q, QueryInfo info, Spring.Data.NHibernate.HibernateAccessor accessor)
{ // LicenseValidator.Validate(); if (info.Transformer != null) { Type transType; transType = info.Transformer as Type; if (transType == null && info.Transformer is string) transType = Type.GetType((string)info.Transformer);if (transType == null)
throw new ArgumentException("Resultset 'Transformer' type could not be found."); q.SetResultTransformer(NHibernate.Transform.Transformers.AliasToBean(transType)); } if (info.NamedQuery != null) { System.Text.StringBuilder sb = null; bool bQueryReplaced = false; IDictionary namedParams = null; string sNullExp = " is null";//prop=:prop => prop is null int iWhere = q.QueryString.IndexOf("where", StringComparison.InvariantCultureIgnoreCase); foreach (System.Collections.Generic.KeyValuePair<string, object> p in info.Parameters)//if (!info.Filters.ContainsKey(p.Key))//bypass filter params { #region 更新Where后语句支持参数NULL值:NamedSQL请不要使同一参数在where前后同时出现! //select Col = :FormType from A where FormType=:FormType => select Col = from A Where FormType is null. //其中where之前的参数为NHibernate替换.NamedSQL请不要使同一参数在where前后同时出现! if (iWhere > 0 && p.Value == null) { bool bReplaced = false;//重置 if (sb == null) sb = new System.Text.StringBuilder(q.QueryString);Regex regex = new Regex(string.Format(@"([=><]+)(\s*):{0}", p.Key));
MatchCollection mc = regex.Matches(sb.ToString()); for (int i = mc.Count - 1; i > -1; i--) { Match mt = mc[i]; if (mt.Index > iWhere)//仅更新Where后语句 { sb.Replace(mt.Value, sNullExp, mt.Index, mt.Length); bQueryReplaced = true; bReplaced = true; } }if (bReplaced)//where 后更新成功
{ if (namedParams == null) namedParams = NHibernateHack.GetNamedParameterMap(q); NHibernateHack.AddTypedValue(namedParams, p.Key); continue;//参数不再需要了 } } #endregion accessor.ApplyNamedParameterToQuery(q, p.Key, p.Value, ((p.Value == null || p.Value is string) ? NHibernate.NHibernateUtil.AnsiString : null)); } if (bQueryReplaced)//更新QueryString NHibernateHack.SetQueryString(q, sb.ToString()); } else foreach (System.Collections.Generic.KeyValuePair<string, object> p in info.Parameters) if (!info.Filters.ContainsKey(p.Key))//bypass filter params accessor.ApplyNamedParameterToQuery(q, p.Key, p.Value, ((p.Value == null || p.Value is string) ? NHibernate.NHibernateUtil.AnsiString : null)); }#region Misc
public object SaveOrUpdate(object obj) { Entity o = obj as Entity; if (o == null) throw new ArgumentException("Obj should be inherit from class [Entity]!");if (o.State.New)
Save(obj); else if (o.State.Deleted) Delete(obj); else if (o.State.Dirty) Update(obj);if (o.State.Deleted)//删除时不返回
return null; else return obj; }public void Flush()
{ MHibernateTemplate.Flush(); } public void Evict(object obj) { MHibernateTemplate.Evict(obj); }private int GetUserCount()
{ int i = 0; if (this.adoTemplate != null) { QueryInfo info = new QueryInfo(); info.CustomSQL = "select count(*) from SYS_USER"; i = Convert.ToInt32(this.ExecuteScalar(info)); } return i; } public void Save(object obj) { //if (LicenseValidator.Capacity>0 && obj.GetType().Name == "User")//用户数控制 //{ // int i = GetUserCount(); // if (i > LicenseValidator.Capacity + 1) // throw new UnauthorizedAccessException(string.Format("当前用户数'{0}'已达到授权最大用户数'{1}',无法再新增用户.", i,LicenseValidator.Capacity)); //} MHibernateTemplate.Save(obj); }public void Update(object obj)
{ MHibernateTemplate.Update(obj); }public void Delete(object obj)
{ MHibernateTemplate.Delete(obj); }/// <summary>
/// 请不要使同一参数在where前后同时出现! /// </summary> public int ExecuteUpdate(QueryInfo info) { int i = (int)MHibernateTemplate.Execute(delegate(ISession session1) { IQuery q = null; if (info.NamedQuery == null) { info.QueryObject = info.ToHQLString(); foreach (System.Collections.Generic.KeyValuePair<string, string> filter in info.Filters)//Enable Filter session.EnableFilter(filter.Value).SetParameter(filter.Key, info.Parameters[filter.Key]);q = session.CreateQuery(info.QueryObject + info.ToOrderBy());
} else q = session.GetNamedQuery(info.NamedQuery);SetParameters(q, info, MHibernateTemplate);
return q.ExecuteUpdate(); }); return i; } #endregion#endif#if ADO_NET
public object ExecuteScalar(QueryInfo info) { IDbParameters ps = AdoAccessorHelper.PrepareCommand(AdoTemplate, info); object o = AdoTemplate.ExecuteScalar(info.NamedQuery == null ? CommandType.Text : CommandType.StoredProcedure , info.QueryObject, ps);if (info.TotalCount == 1)
AdoAccessorHelper.FetchOutputParameters(ps, info); return o; } public IList ExecuteRowMapper(QueryInfo info, IRowMapper mapper) { IDbParameters ps = AdoAccessorHelper.PrepareCommand(AdoTemplate, info); bool bOutput = false; int i; if (info.TotalCount == 1)//进行分页? { bOutput = true; if (info.NamedQuery == null) { i = info.QueryObject.IndexOf("from", StringComparison.InvariantCultureIgnoreCase);string sCountSQL = string.Format("SELECT COUNT({0}) {1}", info.CountField
, info.QueryObject.Substring(i));//from ... info.TotalCount = Convert.ToInt32(AdoTemplate.ExecuteScalar(CommandType.Text, sCountSQL, ps)); AdoAccessorHelper.BuildPagingSQL(AdoTemplate, info); //if (AdoTemplate.DbProvider.DbMetadata.ParameterNamePrefix == "?") //{ // mapper.Start = info.StartRecord; // mapper.Limit = info.PageSize; //} } } IList li = AdoTemplate.QueryWithRowMapper(info.NamedQuery == null ? CommandType.Text : CommandType.StoredProcedure , info.QueryObject + info.ToOrderBy(), mapper, ps); if (bOutput) AdoAccessorHelper.FetchOutputParameters(ps, info); return li;}
[Obsolete] public IList ExecuteRowMapper(QueryInfo info, Type type) { IDbParameters ps = AdoAccessorHelper.PrepareCommand(AdoTemplate, info); ClassicRowMapper mapper = new ClassicRowMapper(type); bool bOutput = false; int i; if (info.TotalCount == 1)//进行分页? { bOutput = true; if (info.NamedQuery == null) { i = info.QueryObject.IndexOf("from", StringComparison.InvariantCultureIgnoreCase);string sCountSQL = string.Format("SELECT COUNT({0}) {1}", info.CountField
, info.QueryObject.Substring(i));//from ...info.TotalCount = Convert.ToInt32(AdoTemplate.ExecuteScalar(CommandType.Text, sCountSQL, ps));
AdoAccessorHelper.BuildPagingSQL(AdoTemplate, info);
if (AdoTemplate.DbProvider.DbMetadata.ParameterNamePrefix == "?") { mapper.Start = info.StartRecord; mapper.Limit = info.PageSize; } } }IList li = AdoTemplate.QueryWithRowMapper(info.NamedQuery == null ? CommandType.Text : CommandType.StoredProcedure
, info.QueryObject + info.ToOrderBy(), mapper, ps); if (bOutput) AdoAccessorHelper.FetchOutputParameters(ps, info); return li; }public int ExecuteNonQuery(QueryInfo info)
{ IDbParameters ps = AdoAccessorHelper.PrepareCommand(AdoTemplate, info);int i = AdoTemplate.ExecuteNonQuery(info.NamedQuery == null ? CommandType.Text : CommandType.StoredProcedure
, info.QueryObject, ps); if (info.TotalCount == 1) AdoAccessorHelper.FetchOutputParameters(ps, info); return i; }public DataSet ExecuteDataSet(QueryInfo info)
{ IDbParameters ps = AdoAccessorHelper.PrepareCommand(AdoTemplate, info);DataSet ds = new DataSet();
bool bOutput = false; int i; if (info.TotalCount == 1)//进行分页? { bOutput = true; if (info.NamedQuery == null) { i = info.QueryObject.IndexOf("from", StringComparison.InvariantCultureIgnoreCase); if (i < 0) throw new ArgumentException("'from' clause is not found in 'CustomSQL'.");string sCountSQL = string.Format("SELECT COUNT({0}) {1}", info.CountField
, info.QueryObject.Substring(i));//from ...info.TotalCount = Convert.ToInt32(adoTemplate.ExecuteScalar(CommandType.Text, sCountSQL, ps));
AdoAccessorHelper.BuildPagingSQL(AdoTemplate, info);
} } i = AdoTemplate.DataSetFillWithParameters(ds, info.NamedQuery == null ? CommandType.Text : CommandType.StoredProcedure , info.QueryObject + info.ToOrderBy(), ps); if (bOutput) AdoAccessorHelper.FetchOutputParameters(ps, info); return ds; } private AdoTemplate adoTemplate; public AdoTemplate AdoTemplate { get { if (adoTemplate == null) throw new Exception("'ClassicDAO'未被注入AdoTemplate属性,请检查Spring配置."); return adoTemplate; } set { adoTemplate = value; } }#endif#region IClassicDao 成员
public void SaveOrUpdateAll<T>(IList<T> list)where T:Framework.Domain.Entity
{ var session = MHibernateTemplate.SessionFactory.OpenStatelessSession(); using (var tx = session.BeginTransaction()) { try { for (int i = 0; i < list.Count; i++) { T a = list[i]; if (a.State.New||string.IsNullOrEmpty(a.Id)) { session.Insert(a); } else if (a.State.Deleted) { session.Delete(a); } else { session.Update(a); } } tx.Commit(); } catch (Exception ex) { tx.Rollback(); throw ex; } finally { session.Close(); } } } public void SaveOrUpdateAll(IList list) { var session = MHibernateTemplate.SessionFactory.OpenStatelessSession(); //using (var tx = session.BeginTransaction()) //{ // try // { // for (var i = 0; i < list.Count; i++) // { // HibernateTemplate.SaveOrUpdate(list[i]); // //if (i % 100 == 0) // //{ // // HibernateTemplate.Flush(); // // HibernateTemplate.Clear(); // //} // } // tx.Commit(); // } // catch (Exception ex) // { // tx.Rollback(); // throw ex // } // finally // { // session.Close(); // } //} using (var tx = session.BeginTransaction()) { try { int i = 0; foreach(Framework.Domain.Entity a in list) { if (a.State.New || string.IsNullOrEmpty(a.Id)) { session.Insert(list[i]); } else if (a.State.Deleted) { session.Delete(list[i]); } else { session.Update(list[i]); } i++; } tx.Commit(); } catch (Exception ex) { tx.Rollback(); throw ex; } finally { session.Close(); } }}
#endregion
}}