using Ant.DbExpressions; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; namespace Ant.SqlServer { static class DbExpressionExtensions { /// /// 尝试将 exp 转换成 DbParameterExpression。 /// /// /// /// public static bool TryParseToParameterExpression(this DbMemberExpression exp, out DbParameterExpression val) { val = null; if (!exp.CanEvaluate()) return false; //求值 val = exp.ParseToParameterExpression(); return true; } /// /// 尝试将 exp 转换成 DbParameterExpression。 /// /// /// public static DbExpression ParseDbExpression(this DbExpression exp) { DbExpression stripedExp = DbExpressionHelper.StripInvalidConvert(exp); DbExpression tempExp = stripedExp; List cList = null; while (tempExp.NodeType == DbExpressionType.Convert) { if (cList == null) cList = new List(); DbConvertExpression c = (DbConvertExpression)tempExp; cList.Add(c); tempExp = c.Operand; } if (tempExp.NodeType == DbExpressionType.Constant || tempExp.NodeType == DbExpressionType.Parameter) return stripedExp; if (tempExp.NodeType == DbExpressionType.MemberAccess) { DbMemberExpression dbMemberExp = (DbMemberExpression)tempExp; if (ExistDateTime_NowOrDateTime_UtcNow(dbMemberExp)) return stripedExp; DbParameterExpression val; if (DbExpressionExtensions.TryParseToParameterExpression(dbMemberExp, out val)) { if (cList != null) { if (val.Value == DBNull.Value)//如果是 null,则不需要 Convert 了,在数据库里没意义 return val; DbConvertExpression c = null; for (int i = cList.Count - 1; i > -1; i--) { DbConvertExpression item = cList[i]; c = new DbConvertExpression(item.Type, val); } return c; } return val; } } return stripedExp; } public static bool CanEvaluate(this DbMemberExpression memberExpression) { if (memberExpression == null) throw new ArgumentNullException("memberExpression"); do { DbExpression prevExp = memberExpression.Expression; // prevExp == null 表示是静态成员 if (prevExp == null || prevExp is DbConstantExpression) return true; DbMemberExpression memberExp = prevExp as DbMemberExpression; if (memberExp == null) return false; else memberExpression = memberExp; } while (true); } /// /// 对 memberExpression 进行求值 /// /// /// 返回 DbParameterExpression public static DbParameterExpression ParseToParameterExpression(this DbMemberExpression memberExpression) { DbParameterExpression ret = null; //求值 object val = DbExpressionExtensions.GetExpressionValue(memberExpression); ret = DbExpression.Parameter(val, memberExpression.Type); return ret; } /// /// 判定 exp 返回值肯定是 null /// /// /// public static bool AffirmExpressionRetValueIsNull(this DbExpression exp) { exp = DbExpressionHelper.StripConvert(exp); if (exp.NodeType == DbExpressionType.Constant) { var c = (DbConstantExpression)exp; return c.Value == null || c.Value == DBNull.Value; } if (exp.NodeType == DbExpressionType.Parameter) { var p = (DbParameterExpression)exp; return p.Value == null || p.Value == DBNull.Value; } return false; } /// /// 判定 exp 返回值肯定不是 null /// /// /// public static bool AffirmExpressionRetValueIsNotNull(this DbExpression exp) { exp = DbExpressionHelper.StripConvert(exp); if (exp.NodeType == DbExpressionType.Constant) { var c = (DbConstantExpression)exp; return c.Value != null && c.Value != DBNull.Value; } if (exp.NodeType == DbExpressionType.Parameter) { var p = (DbParameterExpression)exp; return p.Value != null && p.Value != DBNull.Value; } return false; } public static object GetMemberAccessExpressionValue(this DbMemberExpression exp, object instance) { if (exp.Member.MemberType == MemberTypes.Field) { return ((FieldInfo)exp.Member).GetValue(instance); } else if (exp.Member.MemberType == MemberTypes.Property) { return ((PropertyInfo)exp.Member).GetValue(instance, null); } throw new NotSupportedException(); } public static object GetExpressionValue(this DbExpression exp) { if (exp.NodeType == DbExpressionType.Constant) return ((DbConstantExpression)exp).Value; if (exp.NodeType == DbExpressionType.MemberAccess) { DbMemberExpression m = (DbMemberExpression)exp; object instance = null; if (m.Expression != null) instance = DbExpressionExtensions.GetExpressionValue(m.Expression); return GetMemberAccessExpressionValue(m, instance); } throw new NotSupportedException(); } public static bool ExistDateTime_NowOrDateTime_UtcNow(this DbMemberExpression exp) { while (exp != null) { if (exp.Member == UtilConstants.PropertyInfo_DateTime_Now || exp.Member == UtilConstants.PropertyInfo_DateTime_UtcNow) { return true; } exp = exp.Expression as DbMemberExpression; } return false; } } }