HqlBuilder

在使用NHibernate中,经常使用查询,又不愿意去写,就写了这个东东,依对象的属性,通过反射来生成查询。

先来看一下使用方式:

一个Filter类:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
    public class UserInfoFilter
ExpandedBlockStart.gifContractedBlock.gif    
{
        
private string logName = null;
        
private string name = null;


        [HqlCondition( EnumHqlCondition.Like)]
        
public string LogName
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (string.IsNullOrEmpty(logName))
                    
return null;
                
else
                    
return logName;
            }

            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                logName 
= value;
            }

        }


        [HqlCondition( EnumHqlCondition.Like)]
        
public string Name
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (string.IsNullOrEmpty(name))
                    
return null;
                
else
                    
return name;
            }

            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                name 
= value;
            }

        }


        [HqlCondition]
        
public DicDept DicDept = null;

        [HqlCondition(
"UserRole.RoleInfo", EnumHqlCondition.EQ)]
        
public RoleInfo RoleInfo = null;

        [HqlCondition(
"DicUseFlag", EnumHqlCondition.NE)]
        
public DicUseFlag Deleted = DicUseFlag.CreateInstance((int)Enums.EnumUseFlag.Deleted);

        [HqlOrder]
        
public string Order = "Id asc";
    }

使用查询:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
        public static IList<UserInfo> List(UserInfoFilter filter)
ExpandedBlockStart.gifContractedBlock.gif        
{
            Debug.Assert(filter 
!= null);
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                

                IQuery query 
= HqlQueryBuilder.BuildFilter<UserInfo>(filter);

                
return query.List<UserInfo>();
            }

        }


下面是实现代码:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Text;
  5using System.Reflection;
  6using System.Diagnostics;
  7using NHibernate;
  8using System.Collections;
  9
 10namespace Grain.Components.NHibernateHelper
 11ExpandedBlockStart.gifContractedBlock.gif{
 12
 13    public class HqlQueryBuildParameter
 14ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 15        private string name;
 16
 17        public string Name
 18ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 19ExpandedSubBlockStart.gifContractedSubBlock.gif            get return name; }
 20ExpandedSubBlockStart.gifContractedSubBlock.gif            set { name = value; }
 21        }

 22
 23        private MemberInfo memberInfo;
 24
 25        public MemberInfo MemberInfo
 26ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 27ExpandedSubBlockStart.gifContractedSubBlock.gif            get return memberInfo; }
 28ExpandedSubBlockStart.gifContractedSubBlock.gif            set { memberInfo = value; }
 29        }

 30
 31        private HqlValidateAttribute hqlAttribute;
 32
 33        public HqlValidateAttribute HqlAttribute
 34ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 35ExpandedSubBlockStart.gifContractedSubBlock.gif            get return hqlAttribute; }
 36ExpandedSubBlockStart.gifContractedSubBlock.gif            set { hqlAttribute = value; }
 37        }

 38
 39
 40
 41        private object value;
 42
 43        public object Value
 44ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 45ExpandedSubBlockStart.gifContractedSubBlock.gif            get return this.value; }
 46ExpandedSubBlockStart.gifContractedSubBlock.gif            set this.value = value; }
 47        }

 48
 49    }

 50
 51
 52ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
 53    /// 依一个Filter对象来生成IQuery
 54    /// 
 55    /// </summary>

 56    public class HqlQueryBuilder
 57ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 58
 59        private static object GetValue(MemberInfo mi,object obj)
 60ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 61            if (mi is FieldInfo)
 62                return ((FieldInfo)mi).GetValue(obj);
 63            else if (mi is PropertyInfo)
 64                return ((PropertyInfo)mi).GetGetMethod().Invoke(obj, null);
 65            else
 66                return null;
 67        }

 68
 69        public static IQuery BuildFilter<T>(object filter)
 70ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 71            return BuildFilter<T>(Database.Session, filter);
 72        }

 73
 74        public static IQuery BuildFilter<T>(object filter, string hqlWhereEx)
 75ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 76            return BuildFilter<T>(Database.Session, filter, hqlWhereEx);
 77        }

 78
 79        public static IQuery BuildFilter<T>(ISession session, object filter)
 80ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 81            return BuildFilter<T>(session, filter, string.Empty);
 82        }

 83
 84        public static IQuery BuildFilter<T>(ISession session, object filter, string hqlWhereEx)
 85ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 86            return BuildFilter(session, typeof(T), filter, hqlWhereEx);
 87        }

 88
 89
 90        public static IQuery BuildFilter(ISession session, Type type, object filter, string hqlWhereEx)
 91ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 92            Type typeFilter = filter.GetType();
 93            string typeClassName = type.Name;
 94            string typeClassPrefix = new string((from c in typeClassName where char.IsUpper(c) == true select c).ToArray<char>()).ToLower();
 95            string orderString = string.Empty;
 96            List<HqlQueryBuildParameter> prms = new List<HqlQueryBuildParameter>();
 97
 98            StringBuilder sb = new StringBuilder(string.Format("from {0} {1}", typeClassName, typeClassPrefix));
 99            MemberInfo[] fis = typeFilter.GetMembers();
100            bool bAddedWhere = false;
101            if (!string.IsNullOrEmpty(hqlWhereEx))
102ExpandedSubBlockStart.gifContractedSubBlock.gif            {
103                sb.AppendFormat(" where {0}", hqlWhereEx.Replace(typeClassName + ".", typeClassPrefix + "."));
104                bAddedWhere = true;
105            }

106            foreach (MemberInfo fi in fis)
107ExpandedSubBlockStart.gifContractedSubBlock.gif            {
108
109                object value = GetValue(fi,filter);
110                if (value == null)
111ExpandedSubBlockStart.gifContractedSubBlock.gif                {
112                    continue;
113                }

114
115                HqlAttribute hqlAttr = (HqlAttribute)Attribute.GetCustomAttribute(fi, typeof(HqlAttribute));
116                if (hqlAttr != null)
117ExpandedSubBlockStart.gifContractedSubBlock.gif                {
118                    if (hqlAttr is HqlIgoreAttribute)
119ExpandedSubBlockStart.gifContractedSubBlock.gif                    {
120                        continue;
121                    }

122                    else if (hqlAttr is HqlValidateAttribute)
123ExpandedSubBlockStart.gifContractedSubBlock.gif                    {
124                        HqlValidateAttribute attrValidate = (HqlValidateAttribute)hqlAttr;
125
126                        if (value is ValueType && IsNullValue(value))
127ExpandedSubBlockStart.gifContractedSubBlock.gif                        {
128                            continue;
129                        }

130
131                        if (!bAddedWhere)
132ExpandedSubBlockStart.gifContractedSubBlock.gif                        {
133                            sb.Append(" where 1=1");
134                            bAddedWhere = true;
135                        }

136                        sb.AppendFormat(" and {0}.{1}", typeClassPrefix, attrValidate.BuildHql(fi, fi.Name));
137
138ExpandedSubBlockStart.gifContractedSubBlock.gif                        prms.Add(new HqlQueryBuildParameter() { Name = fi.Name, Value = value, HqlAttribute = attrValidate, MemberInfo = fi });
139
140
141                    }

142                    else if (hqlAttr is HqlWhereAttribute)
143ExpandedSubBlockStart.gifContractedSubBlock.gif                    {
144                        if (!bAddedWhere)
145ExpandedSubBlockStart.gifContractedSubBlock.gif                        {
146                            sb.Append(" where 1=1");
147                            bAddedWhere = true;
148                        }

149                        sb.AppendFormat(" and {0}", value.ToString().Replace(typeClassName + ".", typeClassPrefix + "."));
150                    }

151                    else if (hqlAttr is HqlOrderAttribute)
152ExpandedSubBlockStart.gifContractedSubBlock.gif                    {
153                        orderString = (string)value;
154                    }

155                    else
156ExpandedSubBlockStart.gifContractedSubBlock.gif                    {
157                        continue;
158                    }

159
160                }

161            }

162
163            if (!string.IsNullOrEmpty(orderString))
164ExpandedSubBlockStart.gifContractedSubBlock.gif            {
165                string hqlOrder = orderString.Replace(typeClassName + ".", typeClassPrefix + ".");
166                if(!hqlOrder.StartsWith(typeClassPrefix + "."))
167                    hqlOrder = typeClassPrefix + "." + hqlOrder;
168
169                sb.AppendFormat(" order by {0}", hqlOrder);
170            }

171
172            IQuery query = session.CreateQuery(sb.ToString());
173
174
175            //设置参数
176            foreach(HqlQueryBuildParameter prm in prms)
177ExpandedSubBlockStart.gifContractedSubBlock.gif            {
178                prm.HqlAttribute.SetParameterValue(query, prm);
179            }

180
181
182            return query;
183
184        }

185
186        private static bool IsNullValue(object value)
187ExpandedSubBlockStart.gifContractedSubBlock.gif        {
188            if(
189                (value is byte||
190                (value is Int32) ||
191                (value is Int16) ||
192                (value is Int64))
193ExpandedSubBlockStart.gifContractedSubBlock.gif            {
194                if(value.Equals(0))
195                    return true;
196
197                return false;
198            }

199            if(value is DateTime)
200ExpandedSubBlockStart.gifContractedSubBlock.gif            {
201                if(value.Equals(DateTime.MinValue))
202                    return true;
203
204                return false;
205            }

206
207            if(value is Guid)
208ExpandedSubBlockStart.gifContractedSubBlock.gif            {
209                if(value.Equals(Guid.Empty))
210                    return true;
211
212                return false;
213            }

214
215
216            throw new NotImplementedException("未对此类型的默认值检查");
217        }

218
219    }

220
221ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
222    /// HQL生成基类
223    /// </summary>

224    public abstract class HqlAttribute : Attribute
225ExpandedSubBlockStart.gifContractedSubBlock.gif    {
226
227    }

228
229ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
230    /// 生成查询时,乎略这个字段
231    /// </summary>

232    public class HqlIgoreAttribute : HqlAttribute
233ExpandedSubBlockStart.gifContractedSubBlock.gif    {
234    }

235
236ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
237    /// 表示这个字段要生成无参数的条件
238    /// </summary>

239    public class HqlWhereAttribute : HqlAttribute
240ExpandedSubBlockStart.gifContractedSubBlock.gif    {
241
242
243    }

244ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
245    /// 表示这个字段用来执行排序
246    /// </summary>

247    public class HqlOrderAttribute : HqlAttribute
248ExpandedSubBlockStart.gifContractedSubBlock.gif    {
249
250    }

251
252    public enum EnumHqlCondition
253ExpandedSubBlockStart.gifContractedSubBlock.gif    {
254ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
255        /// 等于
256        /// </summary>

257        EQ = 0,
258ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
259        /// 大于等于
260        /// </summary>

261        GEQ = 1,
262ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
263        /// 小于
264        /// </summary>

265        LT = 2,
266
267ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
268        /// 不等于
269        /// </summary>

270        NE = 3,
271
272ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
273        /// 小于等于
274        /// </summary>

275        LEQ = 4,
276
277ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
278        /// 相当于SQL的IN运算符
279        /// </summary>

280        IN = 5,
281
282ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
283        /// 使用Like查询,应用的字段要求是字符串,或者正确实现了ToString()方法
284        /// </summary>

285        Like = 6
286
287    }

288
289
290
291ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
292    /// 表示一个字段的查询
293    /// </summary>

294    public abstract class HqlValidateAttribute : HqlAttribute
295ExpandedSubBlockStart.gifContractedSubBlock.gif    {
296ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
297        /// 这个值作用的字段,可以为 PropertyA.ProperyBPropertyN
298        /// </summary>

299        private string targetName = string.Empty;
300        private object nullValue = null;
301
302        public object NullValue
303ExpandedSubBlockStart.gifContractedSubBlock.gif        {
304ExpandedSubBlockStart.gifContractedSubBlock.gif            get return nullValue; }
305ExpandedSubBlockStart.gifContractedSubBlock.gif            set { nullValue = value; }
306        }

307ExpandedSubBlockStart.gifContractedSubBlock.gif        public abstract string Operator get; }
308
309
310        public HqlValidateAttribute()
311ExpandedSubBlockStart.gifContractedSubBlock.gif        {
312
313        }

314        public HqlValidateAttribute(object nullValue)
315ExpandedSubBlockStart.gifContractedSubBlock.gif        {
316            this.nullValue = nullValue;
317        }

318
319
320        public HqlValidateAttribute(string targetName)
321ExpandedSubBlockStart.gifContractedSubBlock.gif        {
322            this.targetName = targetName;
323        }

324        public HqlValidateAttribute(string targetName, object nullValue)
325ExpandedSubBlockStart.gifContractedSubBlock.gif        {
326            this.targetName = targetName;
327            this.nullValue = nullValue;
328        }

329
330
331
332        public string BuildHql(MemberInfo fieldInfo, string paramName)
333ExpandedSubBlockStart.gifContractedSubBlock.gif        {
334            if (string.IsNullOrEmpty(this.targetName))
335ExpandedSubBlockStart.gifContractedSubBlock.gif            {
336                this.targetName = fieldInfo.Name;
337            }

338
339            return BuildHql(this.targetName, paramName);
340        }

341
342        public virtual void SetParameterValue(IQuery query, HqlQueryBuildParameter prm)
343ExpandedSubBlockStart.gifContractedSubBlock.gif        {
344            Type fieldType = null;
345            if (prm.MemberInfo is FieldInfo)
346ExpandedSubBlockStart.gifContractedSubBlock.gif            {
347                FieldInfo fi = (FieldInfo)prm.MemberInfo;
348                fieldType = fi.FieldType;
349            }

350            else if (prm.MemberInfo is PropertyInfo)
351ExpandedSubBlockStart.gifContractedSubBlock.gif            {
352                PropertyInfo pi = (PropertyInfo)prm.MemberInfo;
353                fieldType = pi.PropertyType;
354            }

355
356            object value = prm.Value;
357            string paramName = prm.Name;
358
359            if (fieldType == typeof(byte[]))
360ExpandedSubBlockStart.gifContractedSubBlock.gif            {
361                query.SetBinary(paramName, (byte[])value);
362            }

363            else if (fieldType == typeof(bool))
364ExpandedSubBlockStart.gifContractedSubBlock.gif            {
365                query.SetBoolean(paramName, (bool)value);
366            }

367            else if (fieldType == typeof(byte))
368ExpandedSubBlockStart.gifContractedSubBlock.gif            {
369                query.SetByte(paramName, (byte)value);
370            }

371            else if (fieldType == typeof(char))
372ExpandedSubBlockStart.gifContractedSubBlock.gif            {
373                query.SetCharacter(paramName, (char)value);
374            }

375            else if (fieldType == typeof(DateTime))
376ExpandedSubBlockStart.gifContractedSubBlock.gif            {
377                query.SetDateTime(paramName, (DateTime)value);
378            }

379            else if (fieldType == typeof(decimal))
380ExpandedSubBlockStart.gifContractedSubBlock.gif            {
381                query.SetDecimal(paramName, (decimal)value);
382            }

383            else if (fieldType == typeof(double))
384ExpandedSubBlockStart.gifContractedSubBlock.gif            {
385                query.SetDouble(paramName, (double)value);
386            }

387            else if (fieldType == typeof(Int16))
388ExpandedSubBlockStart.gifContractedSubBlock.gif            {
389                query.SetInt16(paramName, (Int16)value);
390            }

391            else if (fieldType == typeof(Int32))
392ExpandedSubBlockStart.gifContractedSubBlock.gif            {
393                query.SetInt32(paramName, (Int32)value);
394            }

395
396            else if (fieldType == typeof(Int64))
397ExpandedSubBlockStart.gifContractedSubBlock.gif            {
398                query.SetInt64(paramName, (Int64)value);
399            }

400
401            else if (fieldType == typeof(float))
402ExpandedSubBlockStart.gifContractedSubBlock.gif            {
403                query.SetSingle(paramName, (float)value);
404            }

405
406            else if (fieldType == typeof(string))
407ExpandedSubBlockStart.gifContractedSubBlock.gif            {
408                query.SetString(paramName, (string)value);
409            }

410            else if (Database.Configuration.GetClassMapping(fieldType) != null)
411ExpandedSubBlockStart.gifContractedSubBlock.gif            {
412                query.SetEntity(paramName, value);
413            }

414            else
415ExpandedSubBlockStart.gifContractedSubBlock.gif            {
416                query.SetParameter(paramName, value);
417            }

418        }

419
420        public virtual string BuildHql(string targetName, string paramName)
421ExpandedSubBlockStart.gifContractedSubBlock.gif        {
422            return string.Format("{0} {1} :{2}", targetName, this.Operator, paramName);
423        }

424    }

425
426
427ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
428    /// 表示一个字段的查询时,要求Target的属性等于该值
429    /// </summary>

430    public class HqlConditionAttribute : HqlValidateAttribute
431ExpandedSubBlockStart.gifContractedSubBlock.gif    {
432        private EnumHqlCondition condition = EnumHqlCondition.EQ;
433        public override string Operator
434ExpandedSubBlockStart.gifContractedSubBlock.gif        {
435            get
436ExpandedSubBlockStart.gifContractedSubBlock.gif            {
437                string oper = "=";
438                switch (condition)
439ExpandedSubBlockStart.gifContractedSubBlock.gif                {
440                    case EnumHqlCondition.EQ:
441                        oper = "=";
442                        break;
443                    case EnumHqlCondition.GEQ:
444                        oper = ">=";
445                        break;
446                    case EnumHqlCondition.LEQ:
447                        oper = "<=";
448                        break;
449                    case EnumHqlCondition.LT:
450                        oper = "<";
451                        break;
452                    case EnumHqlCondition.NE:
453                        oper = "!=";
454                        break;
455                    case EnumHqlCondition.IN:
456                        oper = "in";
457                        break;
458                    case EnumHqlCondition.Like:
459                        oper = "like";
460                        break;
461                    default:
462                        break;
463
464                }

465                return oper;
466            }

467        }

468
469ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
470        /// 依该字段的名称作为TargetName来进行相等条件的筛选
471        /// </summary>

472        public HqlConditionAttribute()
473            : base()
474ExpandedSubBlockStart.gifContractedSubBlock.gif        {
475
476        }

477
478ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
479        /// 依该字段的名称作为TargetName来筛选
480        /// </summary>
481        /// <param name="condition">条件</param>

482        public HqlConditionAttribute(EnumHqlCondition condition)
483            : base()
484ExpandedSubBlockStart.gifContractedSubBlock.gif        {
485            this.condition = condition;
486        }

487
488
489ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
490        ///  通过指定筛选属性和条件来筛选
491        /// </summary>
492        /// <param name="targetName">筛选属性,可以为 PropertyA.ProperyBPropertyN的形式</param>
493        /// <param name="condition">条件</param>

494        public HqlConditionAttribute(string targetName, EnumHqlCondition condition)
495            : base(targetName)
496ExpandedSubBlockStart.gifContractedSubBlock.gif        {
497            this.condition = condition;
498        }

499
500
501ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
502        /// 依该字段的名称作为TargetName来筛选
503        /// </summary>
504        /// <param name="condition">条件</param>

505        public HqlConditionAttribute(EnumHqlCondition condition, object nullValue)
506            : base(nullValue)
507ExpandedSubBlockStart.gifContractedSubBlock.gif        {
508            this.condition = condition;
509        }

510
511
512ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
513        ///  通过指定筛选属性和条件来筛选
514        /// </summary>
515        /// <param name="targetName">筛选属性,可以为 PropertyA.ProperyBPropertyN的形式</param>
516        /// <param name="condition">条件</param>

517        public HqlConditionAttribute(string targetName, EnumHqlCondition condition, object nullValue)
518            : base(targetName,nullValue)
519ExpandedSubBlockStart.gifContractedSubBlock.gif        {
520            this.condition = condition;
521        }

522
523
524
525
526        public override void SetParameterValue(IQuery query, HqlQueryBuildParameter prm)
527ExpandedSubBlockStart.gifContractedSubBlock.gif        {
528
529            switch (condition)
530ExpandedSubBlockStart.gifContractedSubBlock.gif            {
531                case EnumHqlCondition.IN:
532                    query.SetParameterList(prm.Name, (IEnumerable)prm.Value);
533                    break;
534                case EnumHqlCondition.Like:
535                    query.SetString(prm.Name, string.Format("%{0}%", (string)prm.Value));
536                    break;
537                default:
538                    base.SetParameterValue(query, prm);
539                    break;
540            }

541        }

542
543        public override string BuildHql(string targetName, string paramName)
544ExpandedSubBlockStart.gifContractedSubBlock.gif        {
545            string hql = string.Empty;
546            switch (condition)
547ExpandedSubBlockStart.gifContractedSubBlock.gif            {
548                case EnumHqlCondition.IN:
549                    hql = string.Format("{0} {1} (:{2})", targetName, this.Operator, paramName);
550                    break;
551                default:
552                    hql = base.BuildHql(targetName, paramName);
553                    break;
554            }

555
556            return hql;
557        }

558    }

559
560
561
562
563}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值