您的位置:首页 > 数据库

C# -- lambda表达式转为where条件sql语句的方法2

2018-01-23 20:04 555 查看
/// <summary>
/// 根据Expression表达式生成SQL-Where部分的语句
/// </summary>
public class SqlGenerate
{

///<summary>
/// 生成SQL-Where语句
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="expression">表达式</param>
/// <returns></returns>
public string QueryWhereByLambda<T>(Expression<Func<T, bool>> expression)
{
QueryWhereExpressionVisitor expressionVisitor = new QueryWhereExpressionVisitor();
return expressionVisitor.Extract(expression);
}
}
internal delegate object FunctionReturningObject();
/// <summary>
///
/// </summary>
internal interface IDMSExpressionModifier
{
/// <summary>
///
/// </summary>
/// <param name="expr"></param>
/// <returns></returns>
Expression Modify(Expression expr);
}
/// <summary>
///
/// </summary>
internal class LocalDMSExpressionChecker : ExpressionVisitor
{
private static readonly LocalDMSExpressionChecker Instance = new LocalDMSExpressionChecker();
private bool _foundParameter;
private bool _foundConstant;
private bool _foundSpecialMethod;
private string[] specialMethodName = new string[]
{
"As",
"Len",
};
/// <summary>
///
/// </summary>
/// <param name="expr"></param>
/// <param name="funcReturningObj"></param>
/// <returns></returns>
public static bool TryMatchLocalExpression(Expression expr, out FunctionReturningObject funcReturningObj)
{
bool result;
try
{
LocalDMSExpressionChecker localExpressionChecker = new LocalDMSExpressionChecker();
localExpressionChecker.Visit(expr);
bool flag = localExpressionChecker._foundConstant && !localExpressionChecker._foundParameter && !localExpressionChecker._foundSpecialMethod;
if (flag)
{
funcReturningObj = LocalDMSExpressionChecker.CompileLocalExpression(expr);
}
else
{
funcReturningObj = null;
}
result = flag;
}
catch (Exception arg)
{
Console.WriteLine("TryMatchLocalExpression failed: " + arg);
throw;
}
return result;
}
/// <summary>
///
/// </summary>
/// <param name="expr"></param>
/// <param name="constExpr"></param>
/// <returns></returns>
public static bool TryMatchLocalExpression(Expression expr, out ConstantExpression constExpr)
{
FunctionReturningObject functionReturningObject;
if (LocalDMSExpressionChecker.TryMatchLocalExpression(expr, out functionReturningObject))
{
constExpr = Expression.Constant(functionReturningObject(), expr.Type);
return true;
}
constExpr = null;
return false;
}
/// <summary>
///
/// </summary>
/// <param name="expr"></param>
/// <returns></returns>
public static FunctionReturningObject CompileLocalExpression(Expression expr)
{
Expression body = expr;
if (expr.Type.IsPrimitive())
body = Expression.Convert(expr, typeof(object));
ParameterExpression[] parameters = new ParameterExpression[0];
LambdaExpression lambdaExpression = Expression.Lambda<FunctionReturningObject>(body, parameters);
Delegate @delegate = lambdaExpression.Compile();
return @delegate as FunctionReturningObject;
}
/// <summary>
///
/// </summary>
/// <param name="expr"></param>
/// <returns></returns>
public static ConstantExpression ConvertConstantExpression(Expression expr)
{
FunctionReturningObject functionReturningObject = LocalDMSExpressionChecker.CompileLocalExpression(expr);
return Expression.Constant(functionReturningObject(), expr.Type);
}
/// <summary>
///
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
protected override Expression VisitConstant(ConstantExpression c)
{
this._foundConstant = true;
return base.VisitConstant(c);
}
/// <summary>
///
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
protected override Expression VisitParameter(ParameterExpression p)
{
this._foundParameter = true;
return base.VisitParameter(p);
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
protected override Expression VisitMethodCall(MethodCallExpression m)
{
if (this.specialMethodName.Contains(m.Method.Name))
{
this._foundSpecialMethod = true;
}
return base.VisitMethodCall(m);
}

}
/// <summary>
///
/// </summary>
internal class LocalDMSExpressionModifier : UMS.Framework.Util.ExpressionVisitor, IDMSExpressionModifier
{
internal static readonly IDMSExpressionModifier Instance = new LocalDMSExpressionModifier();
/// <summary>
///
/// </summary>
/// <param name="expr"></param>
/// <returns></returns>
public Expression Modify(Expression expr)
{
return this.Visit(expr);
}
/// <summary>
///
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
protected override Expression VisitBinary(BinaryExpression b)
{
ConstantExpression result;
if (LocalDMSExpressionChecker.TryMatchLocalExpression(b, out result))
return result;
return base.VisitBinary(b);
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
protected override Expression VisitMemberAccess(MemberExpression m)
{
ConstantExpression result;
if (m != null && m.Expression == null)
{
result = LocalDMSExpressionChecker.ConvertConstantExpression(m);
return result;
}
if (LocalDMSExpressionChecker.TryMatchLocalExpression(m, out result))
return result;
return base.VisitMemberAccess(m);
}
/// <summary>
///
/// </summary>
/// <param name="na"></param>
/// <returns></returns>
protected override Expression VisitNewArray(NewArrayExpression na)
{
ConstantExpression result;
if (LocalDMSExpressionChecker.TryMatchLocalExpression(na, out result))
return result;
return base.VisitNewArray(na);
}
/// <summary>
///
/// </summary>
/// <param name="u"></param>
/// <returns></returns>
protected override Expression VisitUnary(UnaryExpression u)
{
ConstantExpression result;
if (LocalDMSExpressionChecker.TryMatchLocalExpression(u, out result))
return result;
return base.VisitUnary(u);
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
protected override Expression VisitMethodCall(MethodCallExpression m)
{
ConstantExpression result;
if (LocalDMSExpressionChecker.TryMatchLocalExpression(m, out result))
return result;
return base.VisitMethodCall(m);
}
}
/// <summary>
///
/// </summary>
internal class LocalExpressionChecker : ExpressionVisitor
{
private static readonly LocalExpressionChecker Instance = new LocalExpressionChecker();

private bool foundParameter;
private bool foundConstant;
private bool foundSpecialMethod;
private string[] specialMethodName = new string[]
{
"As",
"Len",
};

/// <summary>
///
/// </summary>
/// <param name="expr"></param>
/// <param name="funcReturningObj"></param>
/// <returns></returns>
public static bool TryMatchLocalExpression(Expression expr, out FunctionReturningObject funcReturningObj)
{
bool result;
try
{
LocalExpressionChecker localExpressionChecker = new LocalExpressionChecker();
localExpressionChecker.Visit(expr);
bool flag = localExpressionChecker.foundConstant && !localExpressionChecker.foundParameter && !localExpressionChecker.foundSpecialMethod;
if (flag)
{
funcReturningObj = LocalExpressionChecker.CompileLocalExpression(expr);
}
else
{
funcReturningObj = null;
}
result = flag;
}
catch (Exception arg)
{
Console.WriteLine("TryMatchLocalExpression failed: " + arg);
throw;
}
return result;
}
/// <summary>
///
/// </summary>
/// <param name="expr"></param>
/// <param name="constExpr"></param>
/// <returns></returns>
public static bool TryMatchLocalExpression(Expression expr, out ConstantExpression constExpr)
{
FunctionReturningObject functionReturningObject;
if (LocalExpressionChecker.TryMatchLocalExpression(expr, out functionReturningObject))
{
constExpr = Expression.Constant(functionReturningObject(), expr.Type);
return true;
}
constExpr = null;
return false;
}
/// <summary>
///
/// </summary>
/// <param name="expr"></param>
/// <returns></returns>
public static FunctionReturningObject CompileLocalExpression(Expression expr)
{
Expression body = expr;
if (TypeTools.IsPrimitive(expr.Type))
body = Expression.Convert(expr, typeof(object));
ParameterExpression[] parameters = new ParameterExpression[0];
LambdaExpression lambdaExpression = Expression.Lambda<FunctionReturningObject>(body, parameters);
Delegate @delegate = lambdaExpression.Compile();
return @delegate as FunctionReturningObject;
}
/// <summary>
///
/// </summary>
/// <param name="expr"></param>
/// <returns></returns>
public static ConstantExpression ConvertConstantExpression(Expression expr)
{
FunctionReturningObject functionReturningObject = LocalExpressionChecker.CompileLocalExpression(expr);
return Expression.Constant(functionReturningObject(), expr.Type);
}
/// <summary>
///
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
protected override Expression VisitConstant(ConstantExpression c)
{
this.foundConstant = true;
return base.VisitConstant(c);
}
/// <summary>
///
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
protected override Expression VisitParameter(ParameterExpression p)
{
this.foundParameter = true;
return base.VisitParameter(p);
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
protected override Expression VisitMethodCall(MethodCallExpression m)
{
if (this.specialMethodName.Contains(m.Method.Name))
this.foundSpecialMethod = true;
return base.VisitMethodCall(m);
}

}

/// <summary>
///  where语句条件生成
/// </summary>
internal sealed class QueryWhereExpressionVisitor : ExpressionVisitor
{
private StringBuilder stringBuilder = new StringBuilder();
private bool bConstantStartWith = false;
private bool bConstantEndWith = false;

/// <summary>
/// 查询条件使用属性或者方法或者字段代替常量时使用
/// </summary>
private string memberName = string.Empty;

/// <summary>
/// 执行表达式解析
/// </summary>
/// <param name="exp">表达式</param>
/// <param name="paramList">参数集合</param>
/// <returns></returns>
public string Extract(Expression exp)
{
if (exp == null)
return string.Empty;
Expression expression = LocalDMSExpressionModifier.Instance.Modify(exp);
this.Visit(expression);
return stringBuilder.ToString();
}
/// <summary>
///
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
protected override Expression VisitConstant(ConstantExpression c)
{
StringBuilder sbstring = new StringBuilder();
if (c.Value != null && c.Type.IsArray)
{
Array array = c.Value as Array;
foreach (object current in array)
{
if (current != null)
this.AdjustConstant(current, ref sbstring);
else
sbstring.Append(" null ");
sbstring.Append(",");
}
this.stringBuilder.Append(sbstring.ToString().Trim(new char[] { ',' }));
}
else
{
if (c.Value != null)
{
this.AdjustConstant(c.Value, ref sbstring);
this.stringBuilder.Append(sbstring.ToString());
}
else
this.stringBuilder.Append(" null ");
}
return base.VisitConstant(c);
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
protected override Expression VisitMethodCall(MethodCallExpression m)
{
if (m == null)
return m;
string methodName = m.Method.Name;
MethodInfo method = typeof(QueryWhereExpressionVisitor).GetMethod(methodName);
if (method != null)
{
if (methodName.ToUpper() == "SQLLIKE")
this.bConstantStartWith = this.bConstantEndWith = true;
else if (methodName.ToUpper() == "SQLSTARTWITH")
this.bConstantStartWith = true;
else if (methodName.ToUpper() == "SQLENDWITH")
this.bConstantStartWith = true;
Expression exp = method.Invoke(this, new object[] { m }) as System.Linq.Expressions.Expression;
this.bConstantStartWith = this.bConstantEndWith = false;
return exp;
}
return base.VisitMethodCall(m);
}
/// <summary>
///
/// </summary>
/// <param name="na"></param>
/// <returns></returns>
protected override Expression VisitNewArray(NewArrayExpression na)
{
foreach (Expression current in na.Expressions)
{
this.Visit(current);
this.stringBuilder.Append(" ");
}
return na;
}
/// <summary>
///
/// </summary>
/// <param name="u"></param>
/// <returns></returns>
protected override Expression VisitUnary(UnaryExpression u)
{
return base.VisitUnary(u);
}
/// <summary>
///
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
protected override Expression VisitBinary(BinaryExpression b)
{
this.stringBuilder.Append("(");
this.Visit(b.Left);
this.stringBuilder.Append(" " + ExpressionsHelper.FormatOperation(b.NodeType) + " ");
this.Visit(b.Right);
this.stringBuilder.Append(")");
return b;
}
/// <summary>
/// 访问MemberAccess表达式
/// </summary>
/// <param name="m">字段或者属性的表达式</param>
/// <returns></returns>
protected override Expression VisitMemberAccess(MemberExpression m)
{
if (m.Expression is ParameterExpression)
{
base.VisitMemberAccess(m);
//当前为属性名称=>将转换为字段名称
string columnName = m.Member.Name;
stringBuilder.Append(columnName);
return m;
}
if (m.Expression is ConstantExpression)
{
//属性名
//暂无支持方法名、字段名
this.memberName = m.Member.Name;
}
return base.VisitMemberAccess(m);
}
/// <summary>
/// 填充具体的值
/// </summary>
/// <param name="value">要附加的值</param>
/// <param name="sbString">要填充到的可变字符串值</param>
private void AdjustConstant(object value, ref StringBuilder sbString)
{
Type type = value.GetType();
if (type == typeof(string) || type == typeof(bool) || type == typeof(DateTime) || type == typeof(Guid))
{
if (bConstantStartWith)
value = value + "%";
if (bConstantEndWith)
value = "%" + value;
if (type != typeof(bool))
sbString.AppendFormat("'{0}'", value.ToString().Replace("'", "''"));
else
sbString.AppendFormat("{0}", ((bool)value) ? "1" : "0");
}
else
{
if (type.IsClass)
{
sbString.AppendFormat("'{0}'", type.GetProperty(this.memberName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static).GetValue(value, null));
return;
}
if (bConstantStartWith)
value = value + "%";
if (bConstantEndWith)
value = "%" + value;
sbString.AppendFormat("'{0}'", value);
}
}
/// <summary>
/// 处理in关键字
/// </summary>
/// <param name="m">表示方法调用</param>
/// <returns>返回表达式</returns>
public Expression HandleSqlIn(MethodCallExpression m)
{
this.stringBuilder.Append("(");
this.Visit(m.Arguments[0]);
this.stringBuilder.Append(" in (");
if (m.Arguments[1].Type.BaseType == typeof(Array))
{
UnaryExpression castMethodCall = Expression.Convert(m.Arguments[1], typeof(Array));
LambdaExpression exp = Expression.Lambda(castMethodCall);
var dynamicObject = exp.Compile();
var obj = dynamicObject.DynamicInvoke() as Array;
for (int index = 0; index < obj.Length; index++)
{
AdjustConstant(obj.GetValue(index), ref this.stringBuilder);
this.stringBuilder.Append(",");
}
this.stringBuilder = this.stringBuilder.Remove(this.stringBuilder.Length - 1, 1);
}
else
this.Visit(m.Arguments[1]);
this.stringBuilder.Append("))");
return m;
}
/// <summary>
/// 处理not in关键字
/// </summary>
/// <param name="m">表示方法调用</param>
/// <returns>返回表达式</returns>
public Expression HandleSqlNotIn(MethodCallExpression m)
{
this.stringBuilder.Append("(");
this.Visit(m.Arguments[0]);
this.stringBuilder.Append(" not in (");
if (m.Arguments[1].Type.BaseType == typeof(Array))
{
UnaryExpression castMethodCall = Expression.Convert(m.Arguments[1], typeof(Array));
LambdaExpression exp = Expression.Lambda(castMethodCall);
var dynamicObject = exp.Compile();
var obj = dynamicObject.DynamicInvoke() as Array;
for (int index = 0; index < obj.Length; index++)
{
AdjustConstant(obj.GetValue(index), ref this.stringBuilder);
this.stringBuilder.Append(",");
}
this.stringBuilder = this.stringBuilder.Remove(this.stringBuilder.Length - 1, 1);
}
else
this.Visit(m.Arguments[1]);
this.stringBuilder.Append("))");
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression HandleSqlLike(MethodCallExpression m)
{
this.stringBuilder.Append("(");
this.Visit(m.Arguments[0]);
this.stringBuilder.Append(" like ");
this.Visit(m.Arguments[1]);
this.stringBuilder.Append(")");
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression StartWith(MethodCallExpression m)
{
this.stringBuilder.Append("(");
this.Visit(m.Arguments[0]);
this.stringBuilder.Append(" like ");
this.Visit(m.Arguments[1]);
this.stringBuilder.Append(")");
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression EndWith(MethodCallExpression m)
{
this.stringBuilder.Append("(");
this.Visit(m.Arguments[0]);
this.stringBuilder.Append(" like ");
this.Visit(m.Arguments[1]);
this.stringBuilder.Append(")");
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression Equals(MethodCallExpression m)
{
this.stringBuilder.Append("(");
if (m.Object != null)
this.Visit(m.Object);
this.stringBuilder.Append(" = ");
this.Visit(m.Arguments[0]);
this.stringBuilder.Append(")");
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression SameAS(MethodCallExpression m)
{
object value = LocalExpressionChecker.ConvertConstantExpression(m.Arguments[1]).Value;
this.stringBuilder.Append(" (");
this.Visit(m.Arguments[0]);
this.stringBuilder.AppendFormat(" = '{0}'", value);
this.stringBuilder.Append(")");
return m;
}
/// <summary>
///
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression ToString(MethodCallExpression m)
{
this.stringBuilder.Append("'");
if (m.Object != null)
this.Visit(m.Object);
this.stringBuilder.Append("'");
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression IsNull(MethodCallExpression m)
{
this.stringBuilder.Append("(");
this.Visit(m.Arguments[0]);
this.stringBuilder.Append(" IS NULL)");
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression IsNotNull(MethodCallExpression m)
{
this.stringBuilder.Append("(");
this.Visit(m.Arguments[0]);
this.stringBuilder.Append(" IS NOT NULL)");
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression CountAll(MethodCallExpression m)
{
this.stringBuilder.Append(" Count(*) ");
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression Count(MethodCallExpression m)
{
this.MethodFunc(m.Method.Name, m);
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression Len(MethodCallExpression m)
{
this.MethodFunc(m.Method.Name, m);
return m;
}
/// <summary>
/// /
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression Max(MethodCallExpression m)
{
this.MethodFunc(m.Method.Name, m);
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression Min(MethodCallExpression m)
{
this.MethodFunc(m.Method.Name, m);
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression Avg(MethodCallExpression m)
{
this.MethodFunc(m.Method.Name, m);
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression Sum(MethodCallExpression m)
{
this.MethodFunc(m.Method.Name, m);
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression As(MethodCallExpression m)
{
this.Visit(m.Arguments[0]);
object value = LocalExpressionChecker.ConvertConstantExpression(m.Arguments[1]).Value;
if (value != null)
{
this.stringBuilder.Append(" AS ");
this.stringBuilder.Append(value);
}
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression Coalesce(MethodCallExpression m)
{
object value = LocalExpressionChecker.ConvertConstantExpression(m.Arguments[1]).Value;
this.stringBuilder.Append(" coalesce(");
this.Visit(m.Arguments[0]);
//this.stringBuilder.Append(",");
if (m.Arguments[1].GetType() == typeof(string))
this.stringBuilder.Append(",'" + value + "'");
else
this.stringBuilder.Append("," + value);
this.stringBuilder.Append(")");
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression NewID(MethodCallExpression m)
{
return m;
}
/// <summary>
///
/// </summary>
/// <param name="methodName"></param>
/// <param name="m"></param>
private void MethodFunc(string methodName, MethodCallExpression m)
{
if (methodName.StartsWith("sql", StringComparison.OrdinalIgnoreCase))
methodName = methodName.Remove(0, 3);
this.stringBuilder.Append(" " + methodName.ToLower() + "(");
this.Visit(m.Arguments[0]);
this.stringBuilder.Append(") ");
}
public Expression GreaterThan(MethodCallExpression m)
{
this.CompareFunc(">", m);
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression GreaterThanOrEqual(MethodCallExpression m)
{
this.CompareFunc(">=", m);
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression LessThan(MethodCallExpression m)
{
this.CompareFunc("<", m);
return m;
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Expression LessThanOrEqual(MethodCallExpression m)
{
this.CompareFunc("<=", m);
return m;
}

/// <summary>
///
/// </summary>
/// <param name="compareStr"></param>
/// <param name="m"></param>
private void CompareFunc(string compareStr, MethodCallExpression m)
{
this.stringBuilder.Append("(");
this.Visit(m.Arguments[0]);
this.stringBuilder.Append(" " + compareStr + " ");
this.Visit(m.Arguments[1]);
this.stringBuilder.Append(")");
}
}

/// <summary>
///
/// </summary>
internal class RemoveNullDMSExpressionModifier : ExpressionVisitor, IDMSExpressionModifier
{
internal static readonly IDMSExpressionModifier Instance = new RemoveNullDMSExpressionModifier();

/// <summary>
///
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>
public Expression Modify(Expression expression)
{
return this.Visit(expression);
}

/// <summary>
///
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
protected override Expression VisitBinary(BinaryExpression b)
{
Expression expression = this.Visit(b.Left);
Expression expression2 = this.Visit(b.Right);
Expression expression3 = this.Visit(b.Conversion);
if (expression == null || expression2 == null)
{
if (b.NodeType == ExpressionType.LessThan
|| b.NodeType == ExpressionType.LessThanOrEqual
|| b.NodeType == ExpressionType.GreaterThan
|| b.NodeType == ExpressionType.GreaterThanOrEqual
|| b.NodeType == ExpressionType.Equal
|| b.NodeType == ExpressionType.NotEqual)
return null;
if (expression == null)
return expression2;
if (expression2 == null)
return expression;
}
if (expression == b.Left && expression2 == b.Right && expression3 == b.Conversion)
return b;
if (b.NodeType == ExpressionType.Coalesce && b.Conversion != null)
return Expression.Coalesce(expression, expression2, expression3 as LambdaExpression);
return Expression.MakeBinary(b.NodeType, expression, expression2, b.IsLiftedToNull, b.Method);
}

/// <summary>
///
/// </summary>
/// <param name="na"></param>
/// <returns></returns>
protected override Expression VisitNewArray(NewArrayExpression na)
{
IEnumerable<Expression> enumerable = this.VisitExpressionList(na.Expressions);
enumerable = from t in enumerable
where t != null
select t;
if (enumerable.Count<Expression>() == 0)
return null;
if (enumerable == na.Expressions)
return na;
if (na.NodeType == ExpressionType.NewArrayInit)
return Expression.NewArrayInit(na.Type.GetElementType(), enumerable);
return Expression.NewArrayBounds(na.Type.GetElementType(), enumerable);
}

/// <summary>
///
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
protected override Expression VisitMethodCall(MethodCallExpression m)
{
Expression expression = this.Visit(m.Object);
IEnumerable<Expression> enumerable = this.VisitExpressionList(m.Arguments);
enumerable =
from t in enumerable
where t != null
select t;
if (enumerable.Count<Expression>() != m.Arguments.Count)
return null;
if (expression != m.Object || enumerable != m.Arguments)
return Expression.Call(expression, m.Method, enumerable);
return m;
}

/// <summary>
///
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
protected override Expression VisitConstant(ConstantExpression c)
{
if (c.Value == null)
return null;
if (c.Value.GetType().IsArray)
{
bool flag = true;
Array array = c.Value as Array;
foreach (object current in array)
{
if (current != null)
{
flag = false;
break;
}
}
if (flag)
return null;
}
return c;
}

/// <summary>
///
/// </summary>
/// <param name="u"></param>
/// <returns></returns>
protected override Expression VisitUnary(UnaryExpression u)
{
Expression expression = this.Visit(u.Operand);
if (expression == null)
return null;
if (expression != u.Operand)
return Expression.MakeUnary(u.NodeType, expression, u.Type, u.Method);
return u;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c# lambda sql