SqlHelper简单实现(通过Expression和反射)5.Lambda表达式解析类

时间:2023-12-17 15:49:26

这个ExpressionHelper类,是整个SqlHelper中,最核心的一个类,主要功能就是将Lambda表达式转换为Sql语句。同时这个转换过程比较复杂,所以下面详细讲解一下思路和这个类的作用。

0x01基本

在Sql语句中,主要由表名,字段,条件语句等元素组成,而这些元素中,表名,字段可以由实体表示出来,条件语句可以由Lambda表达式表现出来。

在Sql语句中,条件语句可以说是Select中的核心,其中很多功能和Lambda中提供的方法很相似,比如:

实体:

aaarticlea/png;base64,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" alt="" />

     [TableName("RA_MyBlog_Article")]
public class ArticleEntity
{
[Primary]
[Identity]
//文章ID
public int articleID { get; set; }
//分类ID
public int categoryID { get; set; }
//文章标题
public string articleTitle { get; set; }
//文章版权
public string articleCopyright { get; set; }
//文章创建时间
public DateTime articleDate { get; set; }
//文章摘要
public string articleAbstract { get; set; }
//文章内容
public string articleContain { get; set; }
//文章所属User
public int userID { get; set; }
}
Lambda表达式 Sql表达式
GetList<ArticleEntity>(a=>a.articleID > 1 && a.userID = 1) Select * From RA_MyBlog_Article Where articleID > 1 And userID = 1
GetList<ArticleEntity>(a=>list.Contains(a.articleID)) Select * From RA_MyBlog_Article Where articleID In [list中的元素]
Join<UserEntity,ArticleEntity>((a,b)=>a.UserID == b.UserID) Select * From RA_MyBlog_Article,RA_MyBlog_User Join RA_MyBlog_User On (RA_MyBlog_Article.UserID = RA_MyBlog_User.UserID )

从上表可以看出,由Lambda表达式转换为Sql表达式是完全可能的。

0x02 Lambda表达式

Lambda设计到的内容比较多,大家有兴趣可以去百度找一下这方面的介绍,这里只介绍一些涉及到的部分:

以上面的表达式GetList<ArticleEntity>(a=>a.articleID > 1 && a.userID = 1)为例,其中a=>a.articleID > 1 && a.userID = 1这部分是我们需要的部分。在C#中,由Expression对象负责对Lambda表达式的解析和处理。Expression的子类有很多,分布在System.Linq.Expressions命名空间下,这里用到的有

UnaryExpression:一元表达式,比如取反'!'

ConstantExpression:常量表达式,比如1

MemberExpression:成员表达式,一般为变量,比如a.articleID

MethodCallExpression:函数表达式,比如Contains()

BinaryExpression:二元表达式,比如a.articleID > 1

对于这个例子:a.articleID > 1 && a.userID = 1,整体是一个与类型的二元表达式,左元素为a.articleID > 1,是一个Larger类型的二元表达式,其中左元素是成员表达式,右元素是常量表达式。右元素为a.userID = 1,是一个相等类型的二元表达式,其中左元素是成员表达式,右元素是常量表达式。

2.用到的枚举,没啥可说的,包含了Lambda表达式中常见的元素类型。

 namespace RA.DataAccess.Enumerations
{
public enum EnumNodeType
{
[Description("二元运算符")]
BinaryOperator = ,
[Description("一元运算符")]
UndryOperator = ,
[Description("常量表达式")]
Constant = ,
[Description("成员(变量)")]
MemberAccess = ,
[Description("函数")]
Call = ,
[Description("未知")]
Unknown = -,
[Description("不支持")]
NotSupported = -
}
}

0x03 功能部分

1.判断表达式类型

         /// <summary>
/// 判断表达式类型
/// </summary>
/// <param name="func">lambda表达式</param>
/// <returns></returns>
private static EnumNodeType CheckExpressionType(Expression func)
{
switch (func.NodeType)
{
case ExpressionType.AndAlso:
case ExpressionType.OrElse:
case ExpressionType.Equal:
case ExpressionType.GreaterThanOrEqual:
case ExpressionType.LessThanOrEqual:
case ExpressionType.GreaterThan:
case ExpressionType.LessThan:
case ExpressionType.NotEqual:
return EnumNodeType.BinaryOperator;
case ExpressionType.Constant:
return EnumNodeType.Constant;
case ExpressionType.MemberAccess:
return EnumNodeType.MemberAccess;
case ExpressionType.Call:
return EnumNodeType.Call;
case ExpressionType.Not:
case ExpressionType.Convert:
return EnumNodeType.UndryOperator;
default:
return EnumNodeType.Unknown;
}
}

2.判断一元表达式:

         /// <summary>
/// 判断一元表达式
/// </summary>
/// <param name="func"></param>
/// <returns></returns>
private static string VisitUnaryExpression(UnaryExpression func)
{
var result = ExpressionTypeToString(func.NodeType);
var funcType = CheckExpressionType(func.Operand);
switch (funcType)
{
case EnumNodeType.BinaryOperator:
return result + VisitBinaryExpression(func.Operand as BinaryExpression);
case EnumNodeType.Constant:
return result + VisitConstantExpression(func.Operand as ConstantExpression);
case EnumNodeType.Call:
return result + VisitMethodCallExpression(func.Operand as MethodCallExpression);
case EnumNodeType.UndryOperator:
return result + VisitUnaryExpression(func.Operand as UnaryExpression);
case EnumNodeType.MemberAccess:
return result + VisitMemberAccessExpression(func.Operand as MemberExpression);
default:
throw new NotSupportedException("不支持的操作在一元操作处理中:" + funcType.GetDescription());
}
}

3.判断常量表达式:

         /// <summary>
/// 判断常量表达式
/// </summary>
/// <param name="func"></param>
/// <returns></returns>
private static string VisitConstantExpression(ConstantExpression func)
{
if (func.Value.ToString() == "")
{
return "\'\' ";
}
else if (func.Value.ToString() == "True")
{
return "1 = 1 ";
}
else if (func.Value.ToString() == "False")
{
return "0 = 1 ";
}
else
{
return "'" + func.Value.ToString() + "' "; }
}

4.判断变量表达式

         /// <summary>
/// 判断包含变量的表达式
/// </summary>
/// <param name="func"></param>
/// <returns></returns>
private static string VisitMemberAccessExpression(MemberExpression func)
{
try
{
var tablename = EntityHelper.GetTableName(func.Expression.Type);
return tablename + "." + func.Member.Name + " ";
}catch
{
object value;
switch (func.Type.Name)
{
case "Int32":
{
var getter = Expression.Lambda<Func<int>>(func).Compile();
value = getter();
}
break;
case "String":
{
var getter = Expression.Lambda<Func<string>>(func).Compile();
value = "'" + getter() + "'";
}
break;
case "DateTime":
{
var getter = Expression.Lambda<Func<DateTime>>(func).Compile();
value = "'" + getter() + "'";
}
break;
default:
{
var getter = Expression.Lambda<Func<object>>(func).Compile();
value = getter();
}
break;
}
return value.ToString();
}
}

5.判断函数表达式:为了演示,此处这个表达式只支持Contains()函数,其他的函数可以按需添加。

         /// <summary>
/// 判断包含函数的表达式
/// </summary>
/// <param name="func"></param>
/// <returns></returns>
private static String VisitMethodCallExpression(MethodCallExpression func)
{
if (func.Method.Name.Contains("Contains"))
{
//获得调用者的内容元素
var getter = Expression.Lambda<Func<object>>(func.Object).Compile();
var data = getter() as IEnumerable;
//获得字段
var caller = func.Arguments[];
while (caller.NodeType == ExpressionType.Call)
{
caller = (caller as MethodCallExpression).Object;
}
var field = VisitMemberAccessExpression(caller as MemberExpression);
var list = (from object i in data select "'" + i + "'").ToList();
return field + " IN (" + string.Join(",", list.Cast<string>().ToArray()) + ") ";
}
else
{
throw new NotSupportedException("不支持的函数操作:" + func.Method.Name);
}
}

6.判断二元表达式:二元表达式一般由其他表达式组成,有时还会有嵌套的情况,所以此处使用递归来解析。

         /// <summary>
/// 判断包含二元运算符的表达式
/// </summary>
/// <remarks>注意,这个函数使用了递归,修改时注意不要修改了代码顺序和逻辑</remarks>
/// <param name="func"></param>
private static string VisitBinaryExpression(BinaryExpression func)
{
var result = "(";
var leftType = CheckExpressionType(func.Left);
switch (leftType)
{
case EnumNodeType.BinaryOperator:
result += VisitBinaryExpression(func.Left as BinaryExpression);break;
case EnumNodeType.Constant:
result += VisitConstantExpression(func.Left as ConstantExpression);break;
case EnumNodeType.MemberAccess:
result += VisitMemberAccessExpression(func.Left as MemberExpression);break;
case EnumNodeType.UndryOperator:
result += VisitUnaryExpression(func.Left as UnaryExpression);break;
case EnumNodeType.Call:
result += VisitMethodCallExpression(func.Left as MethodCallExpression);break;
default:
throw new NotSupportedException("不支持的操作在二元操作处理中:" + leftType.GetDescription());
} result += ExpressionTypeToString(func.NodeType) + " "; var rightType = CheckExpressionType(func.Right);
switch (rightType)
{
case EnumNodeType.BinaryOperator:
result += VisitBinaryExpression(func.Right as BinaryExpression); break;
case EnumNodeType.Constant:
result += VisitConstantExpression(func.Right as ConstantExpression); break;
case EnumNodeType.MemberAccess:
result += VisitMemberAccessExpression(func.Right as MemberExpression); break;
case EnumNodeType.UndryOperator:
result += VisitUnaryExpression(func.Right as UnaryExpression); break;
case EnumNodeType.Call:
result += VisitMethodCallExpression(func.Right as MethodCallExpression); break;
default:
throw new NotSupportedException("不支持的操作在二元操作处理中:" + rightType.GetDescription());
} result += ") ";
return result;
}

7.将Lambda表达式转换为Sql语句。整个类的入口点:

         /// <summary>
/// 通过Lambda解析为Sql
/// </summary>
/// <param name="func"></param>
/// <returns></returns>
public static string GetSqlByExpression(Expression func)
{
var funcType = CheckExpressionType(func);
switch (funcType)
{
case EnumNodeType.BinaryOperator:
return FormatSqlExpression(VisitBinaryExpression(func as BinaryExpression));
case EnumNodeType.Constant:
return FormatSqlExpression(VisitConstantExpression(func as ConstantExpression));
case EnumNodeType.Call:
return FormatSqlExpression(VisitMethodCallExpression(func as MethodCallExpression));
case EnumNodeType.UndryOperator:
return FormatSqlExpression(VisitUnaryExpression(func as UnaryExpression));
case EnumNodeType.MemberAccess:
return FormatSqlExpression(VisitMemberAccessExpression(func as MemberExpression));
default:
throw new NotSupportedException("不支持的操作在表达式处理中:" + funcType.GetDescription());
}
}