This commit is contained in:
sunkaixuan
2017-02-26 20:37:02 +08:00
parent 51a2a6526f
commit 77259b214b
14 changed files with 18 additions and 1297 deletions

View File

@@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SqlSugar
{
public partial class LambdaExpressionsProvider : ILambdaExpressions
{
public SqlSugarClient Context { get; set; }
}
}

View File

@@ -1,123 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SqlSugar
{
//局部类:拉姆达解析公用常量
internal partial class ResolveExpress
{
/// <summary>
/// 解析bool类型用到的字典
/// </summary>
public static List<ExpressBoolModel> ConstantBoolDictionary = new List<ExpressBoolModel>()
{
new ExpressBoolModel(){ Key=Guid.NewGuid(), OldValue="True", Type=PubConst.StringType},
new ExpressBoolModel(){ Key=Guid.NewGuid(), OldValue="False",Type=PubConst.StringType},
new ExpressBoolModel(){ Key=Guid.NewGuid(), OldValue="True",Type=PubConst.BoolType},
new ExpressBoolModel(){ Key=Guid.NewGuid(), OldValue="False",Type=PubConst.BoolType}
};
/// <summary>
/// 字段名解析错误
/// </summary>
public const string FileldErrorMessage = "OrderBy、GroupBy、In、Min和Max等操作不是有效拉姆达格式 ,正确格式 it=>it.name 。";
/// <summary>
/// 拉姆达解析错误
/// </summary>
public const string ExpToSqlError= @"拉姆达解析出错,不是有效的函数,找不到合适函数你可以使用这种字符串写法.Where(""date>dateadd(@date)"",new{date=DateTime.Now})
支持的函数有(请复制到本地查看,数量比较多):
db.Queryable<T>().Where(it => it.field == parValue.ObjToString());
db.Queryable<T>().Where(it => it.field == parValue.ObjToDate());
db.Queryable<T>().Where(it => it.field == parValue.ObjToInt())
db.Queryable<T>().Where(it => it.field == parValue.ObjToDecimal())
db.Queryable<T>().Where(it => it.field == parValue.ObjToMoney())
db.Queryable<T>().Where(it => it.field == parValue.Trim())
db.Queryable<T>().Where(it => it.field == parValue.ToString())
db.Queryable<T>().Where(it => it.field == Convert.ToXXX(parValue))
db.Queryable<T>().Where(it => it.field.Contains(parValue))
db.Queryable<T>().Where(it => it.field.StartsWith(parValue))
db.Queryable<T>().Where(it => it.field.EndsWith(parValue))
db.Queryable<T>().Where(it => !string.IsNullOrEmpty(it.parValue))
db.Queryable<T>().Where(it => arrayOrList.Contains(it.parValue))
db.Queryable<T>().Where(it => it.field.Equals(it.parValue))
db.Queryable<T>().Where(it => it.field.Length>10)
db.Queryable<Student>().Where(c => c.field == parValue.ToLower()).ToList();
db.Queryable<Student>().Where(c => c.field == parValue.ToUpper()).ToList();
";
/// <summary>
/// 运算符错误
/// </summary>
public const string OperatorError = "拉姆达解析出错:不支持{0}此种运算符查找!";
/// <summary>
/// 拉姆达解析唯一标识
/// </summary>
public static object ExpErrorUniqueKey = Guid.NewGuid();
/// <summary>
/// 拉姆达函数错误
/// </summary>
public const string ExpMethodError = "拉姆达表达式中的函数用法不正确,正确写法 it=>it.name.{0}(参数) ,不支持的写法it=> 参数.{0}(it.name)。";
/// <summary>
/// 拉姆达函数错误2
/// </summary>
public const string ExpMethodError2 = "拉姆达表达式中的函数用法不正确,正确写法 it=>it.name==参数.{0} ,不支持的写法it=>it.name.{0}==参数。";
/// <summary>
/// 表达式不支持解析BlockExpression
/// </summary>
public const string ExpBlockExpression = "表达式不支持解析BlockExpression,错误信息:";
/// <summary>
/// 表达式不支解析ConditionalExpression
/// </summary>
public const string ExpConditionalExpression = "表达式不支解析ConditionalExpression,错误信息:";
/// <summary>
/// 拉姆达表达式内不支持new对象
/// </summary>
public const string ExpNew = "拉姆达表达式内不支持new对象请提取变量后在赋值错误信息:";
/// <summary>
/// 不支持对象或属性
/// </summary>
public const string ExpNoSupportObjectOrAttr = "拉姆达解析不支持{0}对象,或该{1}的属性。";
/// <summary>
/// 不支持属性扩展方法
/// </summary>
public const string ExpNoSupportAttExtMethod = "不支持属性扩展方法{0}。";
}
//局部类:Select表达式对象解析公用常量
internal partial class ResolveSelect {
/// <summary>
/// 解析对象不能为null
/// </summary>
public const string ExpSelectValueIsNull = "解析对象不能为null。";
/// <summary>
///Select中不支持函数
/// </summary>
public const string ExpNoSupportMethod = "Select中不支持函数{0}。";
/// <summary>
/// Select中不支持变量的运算
/// </summary>
public const string ExpNoSupportOperation = "Select中不支持变量的运算。";
/// <summary>
/// 不支持外部传参
/// </summary>
public static string ExpNoSupportOutPars = "Select中的拉姆达表达式,不支持外部传参数,目前支持的写法: Where(\"1=1\",new {id=1}).Select(it=>{ id=\"@id\".ObjToInt()} 。";
/// <summary>
/// 不支持ToString
/// </summary>
public static string ExpNoSupportToString = "Select中不支持ToString函数请使用ObjectToString。";
}
}

View File

@@ -1,305 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
namespace SqlSugar
{
//局部类:拉姆达解析分类处理
internal partial class ResolveExpress
{
private string UnaryExpression(Expression exp, ref MemberType type)
{
UnaryExpression ue = ((UnaryExpression)exp);
var mex = ue.Operand;
bool? isComparisonOperator = null;
var isNot = ue.NodeType==ExpressionType.Not;
if (mex.NodeType == ExpressionType.MemberAccess && isNot)
{
isComparisonOperator = false;
}
var cse = CreateSqlElements(mex, ref type, false,isComparisonOperator);
if (type == MemberType.Value && isNot && cse.IsIn("1","0"))
{
cse = cse == "1" ? "0" : "1";
}else if (type == MemberType.None && isNot)
{
cse = " NOT " + cse;
}
return cse;
}
private bool UnderNodeTypeIsConstantExpression(MemberExpression exp)
{
while (exp.Expression != null)
{
if (exp != null && exp.Expression != null)
{
if (exp.Expression is MemberExpression)
{
exp = (MemberExpression)exp.Expression;
}
else
{
break;
}
}
}
return exp.Expression is ConstantExpression;
}
private string MemberExpression(ref Expression exp, ref MemberType type, bool? isComparisonOperator)
{
MemberExpression me = ((MemberExpression)exp);
var isPro = (me.Member.Name == "Length") && me.Member.DeclaringType == PubConst.StringType;
var proIsField = false;
if (isPro) proIsField = me.Expression != null && !UnderNodeTypeIsConstantExpression(me);
if (proIsField==false&&(me.Expression == null || me.Expression.NodeType != ExpressionType.Parameter))
{
type = MemberType.Value;
object dynInv = null;
if (isPro)
{
exp = me.Expression;
dynInv = CreateSqlElements(exp, ref type, true);
}
else {
GetMemberValue(ref exp, me, ref dynInv);
}
if (isPro)return GetProMethod(me.Member.Name,dynInv.ObjToString(),false);
if (dynInv!=null&&dynInv.GetType() == PubConst.BoolType)
{
dynInv = ConstantBoolDictionary.Where(it => it.Type == PubConst.BoolType).Single(it => it.OldValue.ToLower() == dynInv.ObjToString().ToLower()).NewValue;
}
if (dynInv == null) return null;
else
return dynInv.ToString();
}
else if (isComparisonOperator == false)
{
return "(" + me.Member.Name + "=1)";
}
else
{
if (Type == ResolveExpressType.WhereMultiple)
{
type = MemberType.Key;
var dbName = exp.ToString();
if (isPro) return GetProMethod(me.Member.Name, dbName, true);
return dbName;
}
//single T
string name = me.Member.Name;
if (isPro)
{
name = ((me.Expression) as MemberExpression).Member.Name;
}
type = MemberType.Key;
if (isPro) return GetProMethod(me.Member.Name, name, true);
return name;
}
}
private static void GetMemberValue(ref Expression exp, MemberExpression me, ref object dynInv)
{
// var dynInv = Expression.Lambda(exp).Compile().DynamicInvoke();原始写法性能极慢,下面写法性能提高了几十倍
// var dynInv= Expression.Lambda(me.Expression as ConstantExpression).Compile().DynamicInvoke();
SetMemberValueToDynInv(ref exp, me, ref dynInv);
if (dynInv == ExpErrorUniqueKey)//特殊情况走原始写法
{
dynInv = Expression.Lambda(exp).Compile().DynamicInvoke();
if (dynInv != null && dynInv.GetType().IsClass)
{
dynInv = Expression.Lambda(me).Compile().DynamicInvoke();
}
}
}
private static string ConstantExpression(Expression exp, ref MemberType type, bool? isComparisonOperator)
{
type = MemberType.Value;
ConstantExpression ce = ((ConstantExpression)exp);
if (ce.Value == null)
return "null";
else if (ce.Value.ToString().IsIn("True", "False"))//是bool值
{
var ceType = ce.Value.GetType();
var ceValue = ce.Value.ToString();
if (isComparisonOperator==true)
{
var ceNewValue = ConstantBoolDictionary.Single(it => it.Type == ceType && it.OldValue.ToLower() == ceValue.ToLower());
return ceNewValue.NewValue;
}
else
{
var ceNewValue = ConstantBoolDictionary.Single(it => it.Type == ceType && it.OldValue.ToLower() == ceValue.ToLower());
return ceNewValue.Key.ToString();
}
}
else
{
return ce.Value.ToString();
}
}
private string MethodCallExpression(Expression exp, ref MemberType type, bool isTure)
{
MethodCallExpression mce = (MethodCallExpression)exp;
string methodName = mce.Method.Name;
if (methodName == "Contains")
{
return Contains(methodName, mce, isTure);
}
else if (methodName == "StartsWith")
{
return StartsWith(methodName, mce, isTure);
}
else if (methodName == "EndsWith")
{
return EndWith(methodName, mce, isTure);
}
else if (methodName == "ToString")
{
type = MemberType.Value;
return MethodToString(methodName, mce, ref type);
}
else if (methodName == "IsNullOrEmpty")
{
type = MemberType.Value;
return IsNullOrEmpty(methodName, mce, isTure);
}
else if (methodName == "Equals")
{
return Equals(methodName, mce);
}
else
{
type = MemberType.Value;
return ParMethodTo(methodName, mce, ref type);
}
}
private string BinaryExpression(Expression exp)
{
var expression = exp as BinaryExpression;
var isComparisonOperator =
expression.NodeType != ExpressionType.And &&
expression.NodeType != ExpressionType.AndAlso &&
expression.NodeType != ExpressionType.Or &&
expression.NodeType != ExpressionType.OrElse;
MemberType leftType = MemberType.None;
MemberType rightType = MemberType.None;
var leftIsDateTime = expression.Left.Type.ToString().Contains("System.DateTime");
var rightIsDateTime = expression.Right.Type.ToString().Contains("System.DateTime");
var left = CreateSqlElements(expression.Left, ref leftType, true, isComparisonOperator);
var right = CreateSqlElements(expression.Right, ref rightType, true, isComparisonOperator);
var oper = GetOperator(expression.NodeType);
var isKeyOperValue = leftType == MemberType.Key && rightType == MemberType.Value;
var isValueOperKey = rightType == MemberType.Key && leftType == MemberType.Value;
#region null
if (isKeyOperValue && right.IsGuid() && ConstantBoolDictionary.Any(it => it.Key.ToString() == right))
{
right = ConstantBoolDictionary.Single(it => it.Key.ToString() == right).NewValue;
}
if (isValueOperKey && ConstantBoolDictionary.Any(it => it.Key.ToString() == left))
{
left = ConstantBoolDictionary.Single(it => it.Key.ToString() == left).NewValue;
}
if (isKeyOperValue & (right == "null" || right == null) && oper.Trim() == "=")
{
var oldLeft = AddParas(ref left, right);
return string.Format(" ({0} is null ) ", oldLeft);
}
else if (isKeyOperValue & (right == "null" || right == null) && oper.Trim() == "<>")
{
var oldLeft = AddParas(ref left, right);
return string.Format(" ({0} is not null ) ", oldLeft);
}
else if (isValueOperKey & (left == "null" || left == null) && oper.Trim() == "=")
{
return string.Format(" ({0} is null ) ", right);
}
else if (isValueOperKey & (left == "null" || left == null) && oper.Trim() == "<>")
{
return string.Format(" ({0} is not null ) ", right);
}
#endregion
else if (isKeyOperValue)
{
object parValue = null;
if (leftIsDateTime && right != null && right.IsDate())
{
parValue = Convert.ToDateTime(right);
}
else
{
parValue = right;
}
if (left.Contains("("))
{
return string.Format(" ({0} {1} {2}) ",left, oper, right.ToSqlValue());
}
else
{
var oldLeft = AddParas(ref left, parValue);
return string.Format(" ({0} {1} " + this.ParSymbol + "{2}) ",this.SqlBuilder.GetTranslationColumnName(oldLeft), oper, left);
}
}
else if (isValueOperKey)
{
object parValue = null;
if (rightIsDateTime && left != null && left.IsDate())
{
parValue = Convert.ToDateTime(left);
}
else
{
parValue = left;
}
if (right.Contains("("))
{
return string.Format(" ({0} {1} {2}) ", left.ToSqlValue(), oper, right);
}
else
{
var oldRight = AddParasReturnRight(parValue, ref right);
return string.Format("( " + this.ParSymbol + "{0} {1} {2} )", right, oper, this.SqlBuilder.GetTranslationColumnName(oldRight));
}
}
else if (leftType == MemberType.Value && rightType == MemberType.Value)
{
var isAndOr = oper.ObjToString().IsIn("AND","OR");
if (isAndOr)
{
return string.Format("( {0} {1} {2} )", left, oper, right);
}
else
{
return string.Format("( '{0}' {1} '{2}' )", left, oper, right);
}
}
else
{
return string.Format("( {0} {1} {2} )", left, oper, right);
}
}
private string LambdaExpression(Expression exp)
{
LambdaExpression lambda = exp as LambdaExpression;
var expression = lambda.Body;
MemberType EleType = MemberType.None;
if (expression.NodeType == ExpressionType.MemberAccess) {
return "("+((MemberExpression)expression).Member.Name+"=1)";
}
return CreateSqlElements(expression, ref EleType, true);
}
}
}

View File

@@ -1,360 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Reflection;
using System.Text.RegularExpressions;
namespace SqlSugar
{
/// <summary>
/// ** 描述:拉姆达解析类
/// ** 创始时间2015-7-20
/// ** 修改时间2016-9-26
/// ** 作者sunkaixuan
/// ** qq610262374
/// ** 使用说明:使用请注名作者
/// </summary>
internal partial class ResolveExpress
{
public SqlSugarClient Context { get; set; }
private ISqlBuilder SqlBuilder { get; set; }
private ResolveExpress() { }
private string ParSymbol { get; set; }
public ResolveExpress(SqlSugarClient context)
{
this.Context = context;
this.SqlBuilder = context.SqlBuilder;
this.ParSymbol = context.SqlBuilder.SqlParameterKeyWord;
}
/// <summary>
/// 解析拉姆达
/// </summary>
/// <param name="sameIndex">区分相同参数名的索引号</param>
public ResolveExpress(int sameIndex = 1)
{
this.SameIndex = sameIndex;
}
public string SqlWhere = null;
public ResolveExpressType Type = ResolveExpressType.WhereSingle;
public List<SqlParameter> Paras = new List<SqlParameter>();
private int SameIndex = 1;
private SqlSugarClient DB;
/// <summary>
/// 解析表达式
/// </summary>
/// <param name="re">当前解析对象</param>
/// <param name="exp">要解析的表达式</param>
/// <param name="db">数据库访问对象</param>
public void ResolveExpression(Expression exp)
{
DB = this.Context;
//初始化表达式
Init(this, exp);
}
public string GetLeftString(Expression exp)
{
var reval = Regex.Match(exp.ToString(), @"\((.+?)\).+").Groups[1].Value;
return reval;
}
public string[] GetLeftArray(Expression exp)
{
var reval = GetLeftString(exp).Split(',');
return reval;
}
/// <summary>
/// 初始化表达式
/// </summary>
/// <param name="re"></param>
/// <param name="exp"></param>
private void Init(ResolveExpress re, Expression exp)
{
ResolveExpress.MemberType type = ResolveExpress.MemberType.None;
this.SqlWhere = string.Format(" {1} {0} ", re.CreateSqlElements(exp, ref type, true), Context.SqlBuilder.LambadaQueryBuilder.WhereInfos.Count == 0 ? "WHERE" : "AND");
//还原bool值
foreach (var item in ConstantBoolDictionary)
{
if (this.SqlWhere.IsValuable())
{
this.SqlWhere = this.SqlWhere.Replace(item.Key.ToString(), item.ConditionalValue);
}
}
}
/// <summary>
/// 递归解析表达式路由计算
/// </summary>
/// <returns></returns>
private string CreateSqlElements(Expression exp, ref MemberType type, bool isTure, bool? isComparisonOperator = null)
{
//主入口
if (exp is LambdaExpression)
{
return LambdaExpression(exp);
}
else if (exp is BinaryExpression)
{
return BinaryExpression(exp);
}
else if (exp is BlockExpression)
{
throw new SqlSugarException(ExpBlockExpression + exp.ToString());
}
else if (exp is ConditionalExpression)
{
throw new SqlSugarException(ExpConditionalExpression + exp.ToString());
}
else if (exp is MethodCallExpression)
{
return MethodCallExpression(exp, ref type, isTure);
}
else if (exp is ConstantExpression)
{
return ConstantExpression(exp, ref type, isComparisonOperator);
}
else if (exp is MemberExpression)
{
return MemberExpression(ref exp, ref type, isComparisonOperator);
}
else if (exp is UnaryExpression)
{
return UnaryExpression(exp, ref type);
}
else if (exp != null && exp.NodeType.IsIn(ExpressionType.New, ExpressionType.NewArrayBounds, ExpressionType.NewArrayInit))
{
throw new SqlSugarException(ExpNew + exp.ToString());
}
return null;
}
/// <summary>
/// 将解析值赋给dynInv
/// </summary>
/// <param name="exp"></param>
/// <param name="me"></param>
/// <param name="dynInv"></param>
private static void SetMemberValueToDynInv(ref Expression exp, MemberExpression me, ref object dynInv)
{
var conExp = me.Expression as ConstantExpression;
var fieldInfo = me.Member as System.Reflection.FieldInfo;
if (conExp != null && fieldInfo != null)
{
dynInv = (fieldInfo).GetValue((me.Expression as ConstantExpression).Value);
if (fieldInfo.FieldType.IsEnum)
{
dynInv = Convert.ToInt64(Enum.ToObject(fieldInfo.FieldType, dynInv));
}
}
else
{
var memberInfos = new Stack<MemberInfo>();
// "descend" toward's the root object reference:
while (exp is MemberExpression)
{
var memberExpr = exp as MemberExpression;
memberInfos.Push(memberExpr.Member);
if (memberExpr.Expression == null)
{
if (memberExpr.Member.MemberType == MemberTypes.Property)
{
PropertyInfo pro = (PropertyInfo)memberExpr.Member;
dynInv = pro.GetValue(memberExpr.Member, null);
if (dynInv != null && dynInv.GetType().IsClass)
{
var fieldName = me.Member.Name;
var proInfo = dynInv.GetType().GetProperty(fieldName);
if (proInfo != null)
{
dynInv = proInfo.GetValue(dynInv, null);
}
var fieInfo = dynInv.GetType().GetField(fieldName);
if (fieInfo != null)
{
dynInv = fieInfo.GetValue(dynInv);
}
if (fieInfo == null && proInfo == null)
{
throw new SqlSugarException(string.Format(ExpNoSupportObjectOrAttr, dynInv.GetType().FullName, dynInv.GetType().FullName));
}
}
return;
}
else if (memberExpr.Member.MemberType == MemberTypes.Field)
{
FieldInfo field = (FieldInfo)memberExpr.Member;
dynInv = field.GetValue(memberExpr.Member);
if (dynInv != null && dynInv.GetType().IsClass)
{
var fieldName = me.Member.Name;
var proInfo = dynInv.GetType().GetProperty(fieldName);
if (proInfo != null)
{
dynInv = proInfo.GetValue(dynInv, null);
}
var fieInfo = dynInv.GetType().GetField(fieldName);
if (fieInfo != null)
{
dynInv = fieInfo.GetValue(dynInv);
}
if (fieInfo == null && proInfo == null)
{
throw new SqlSugarException(string.Format(ExpNoSupportObjectOrAttr, dynInv.GetType().FullName, dynInv.GetType().FullName));
}
}
return;
}
}
if (memberExpr.Expression == null)
{
dynInv = ExpErrorUniqueKey;
return;
}
exp = memberExpr.Expression;
}
// fetch the root object reference:
var constExpr = exp as ConstantExpression;
if (constExpr == null)
{
dynInv = ExpErrorUniqueKey;
return;
}
var objReference = constExpr.Value;
// "ascend" back whence we came from and resolve object references along the way:
while (memberInfos.Count > 0) // or some other break condition
{
var mi = memberInfos.Pop();
if (mi.MemberType == MemberTypes.Property)
{
var objProp = objReference.GetType().GetProperty(mi.Name);
if (objProp == null)
{
dynInv = ExpErrorUniqueKey;
return;
}
objReference = objProp.GetValue(objReference, null);
}
else if (mi.MemberType == MemberTypes.Field)
{
var objField = objReference.GetType().GetField(mi.Name);
if (objField == null)
{
dynInv = ExpErrorUniqueKey;
return;
}
objReference = objField.GetValue(objReference);
}
}
dynInv = objReference;
}
}
/// <summary>
/// 添加参数
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
private string AddParas(ref string left, object right)
{
string oldLeft = left;
left = left + SameIndex;
SameIndex++;
if (Type != ResolveExpressType.WhereSingle)
{
left = left.Replace(".", "_");
}
if (right == null)
{
this.Paras.Add(new SqlParameter(this.ParSymbol + left, DBNull.Value));
}
else
{
this.Paras.Add(new SqlParameter(this.ParSymbol + left, right));
}
return oldLeft;
}
/// <summary>
/// 添加参数并返回右边值
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
private string AddParasReturnRight(object left, ref string right)
{
string oldRight = right;
right = right + SameIndex;
SameIndex++;
if (Type != ResolveExpressType.WhereSingle)
{
right = right.Replace(".", "_");
}
if (left == null)
{
this.Paras.Add(new SqlParameter(this.ParSymbol + right, DBNull.Value));
}
else
{
this.Paras.Add(new SqlParameter(this.ParSymbol + right, left));
}
return oldRight;
}
/// <summary>
/// 根据条件生成对应的sql查询操作符
/// </summary>
/// <param name="expressiontype"></param>
/// <returns></returns>
private string GetOperator(ExpressionType expressiontype)
{
switch (expressiontype)
{
case ExpressionType.And:
case ExpressionType.AndAlso:
return " AND ";
case ExpressionType.Equal:
return " =";
case ExpressionType.GreaterThan:
return " >";
case ExpressionType.GreaterThanOrEqual:
return ">=";
case ExpressionType.LessThan:
return "<";
case ExpressionType.LessThanOrEqual:
return "<=";
case ExpressionType.NotEqual:
return "<>";
case ExpressionType.Or:
case ExpressionType.OrElse:
return " OR ";
case ExpressionType.Add:
case ExpressionType.AddChecked:
return "+";
case ExpressionType.Subtract:
case ExpressionType.SubtractChecked:
return "-";
case ExpressionType.Divide:
return "/";
case ExpressionType.Multiply:
case ExpressionType.MultiplyChecked:
return "*";
default:
throw new SqlSugarException(string.Format(OperatorError + expressiontype));
}
}
}
}

View File

@@ -1,274 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Collections;
namespace SqlSugar
{
//局部类:解析函数
internal partial class ResolveExpress
{
/// <summary>
/// 是否相等
/// </summary>
/// <param name="methodName"></param>
/// <param name="mce"></param>
/// <returns></returns>
private string Equals(string methodName, MethodCallExpression mce) {
MemberType leftType = MemberType.None;
MemberType rightType = MemberType.None;
var left = CreateSqlElements(mce.Object, ref leftType,true);
var right = mce.Arguments[0].NodeType.IsIn(ExpressionType.Constant, ExpressionType.MemberAccess) ? CreateSqlElements(mce.Arguments[0], ref rightType, true) : Expression.Lambda(mce.Arguments[0]).Compile().DynamicInvoke().ObjToString();
Check.Exception(leftType == MemberType.Value, string.Format(ExpMethodError,methodName));
var oldLeft = AddParas(ref left,right);
return string.Format("({0} = " + this.ParSymbol + "{1})", this.SqlBuilder.GetTranslationColumnName(oldLeft), left);
}
/// <summary>
/// 拉姆达StartsWith函数处理
/// </summary>
/// <param name="methodName"></param>
/// <param name="mce"></param>
/// <param name="isTure"></param>
/// <returns></returns>
private string StartsWith(string methodName, MethodCallExpression mce, bool isTure)
{
MemberType leftType = MemberType.None;
MemberType rightType = MemberType.None;
var left = CreateSqlElements(mce.Object, ref leftType,true);
var right = mce.Arguments[0].NodeType.IsIn(ExpressionType.Constant, ExpressionType.MemberAccess) ? CreateSqlElements(mce.Arguments[0], ref rightType, true) : Expression.Lambda(mce.Arguments[0]).Compile().DynamicInvoke().ObjToString();
Check.Exception(leftType == MemberType.Value, string.Format(ExpMethodError, methodName));
var oldLeft = AddParas(ref left, right + '%');
return string.Format("({0} {1} LIKE " + this.ParSymbol + "{2})", this.SqlBuilder.GetTranslationColumnName(oldLeft), null, left);
}
/// <summary>
/// 拉姆达EndWith函数处理
/// </summary>
/// <param name="methodName"></param>
/// <param name="mce"></param>
/// <param name="isTure"></param>
/// <returns></returns>
private string EndWith(string methodName, MethodCallExpression mce, bool isTure)
{
MemberType leftType = MemberType.None;
MemberType rightType = MemberType.None;
var left = CreateSqlElements(mce.Object, ref leftType,true);
var right = mce.Arguments[0].NodeType.IsIn(ExpressionType.Constant, ExpressionType.MemberAccess) ? CreateSqlElements(mce.Arguments[0], ref rightType, true) : Expression.Lambda(mce.Arguments[0]).Compile().DynamicInvoke().ObjToString();
Check.Exception(leftType == MemberType.Value, string.Format(ExpMethodError, methodName));
var oldLeft = AddParas(ref left, '%' + right);
return string.Format("({0} {1} LIKE " + this.ParSymbol + "{2})", this.SqlBuilder.GetTranslationColumnName(oldLeft), null, left);
}
/// <summary>
/// 拉姆达Contains函数处理
/// </summary>
/// <param name="methodName"></param>
/// <param name="mce"></param>
/// <param name="isTure"></param>
/// <returns></returns>
private string Contains(string methodName, MethodCallExpression mce, bool isTure)
{
MemberType leftType = MemberType.None;
MemberType rightType = MemberType.None;
var left = CreateSqlElements(mce.Object, ref leftType,true);
var right = mce.Arguments[0].NodeType.IsIn(ExpressionType.Constant, ExpressionType.MemberAccess) ? CreateSqlElements(mce.Arguments[0], ref rightType, true) : Expression.Lambda(mce.Arguments[0]).Compile().DynamicInvoke().ObjToString();
if (left.IsCollectionsList() || right.IsStringArray() || right.IsEnumerable())
{
object containsValue = null;
string fieldName = "";
if (left.IsCollectionsList())
{
fieldName = right;
MemberExpression mbx = ((MemberExpression)mce.Object);
Expression exp = mce.Object;
SetMemberValueToDynInv(ref exp, mbx, ref containsValue);
}
else
{
MemberExpression mbx = ((MemberExpression)mce.Arguments[0]);
Expression exp = mce.Arguments[0];
SetMemberValueToDynInv(ref exp, mbx, ref containsValue);
fieldName = CreateSqlElements(mce.Arguments[1], ref rightType,true);
}
List<string> inArray = new List<string>();
foreach (var item in (IEnumerable)containsValue)
{
inArray.Add(item.ObjToString());
}
if (inArray.Count == 0)
{
return (" (1=2) ");
}
var inValue = inArray.ToArray().ToJoinSqlInVals();
return string.Format("({0} IN ({1}))", this.SqlBuilder.GetTranslationColumnName(fieldName), inValue);
}
else if (mce.Arguments.Count == 2) { //两个值
//object containsValue = null;
//MemberExpression mbx = ((MemberExpression)mce.Arguments[0]);
//Expression exp = mce.Arguments[0];
//SetMemberValueToDynInv(ref exp, mbx, ref containsValue);
//var fieldName = CreateSqlElements(mce.Arguments[1], ref rightType);
//return null;
throw new SqlSugarException("请将数组提取成变量,不能直接写在表达式中。");
}
else
{
Check.Exception(leftType == MemberType.Value, string.Format(ExpMethodError, methodName));
var oldLeft = AddParas(ref left, '%' + right + '%');
return string.Format("({0} {1} LIKE " + this.ParSymbol + "{2})", this.SqlBuilder.GetTranslationColumnName(oldLeft), null, left);
}
}
/// <summary>
/// 非空验证
/// </summary>
/// <param name="methodName"></param>
/// <param name="mce"></param>
/// <param name="isTure"></param>
/// <returns></returns>
private string IsNullOrEmpty(string methodName, MethodCallExpression mce, bool isTure)
{
MemberType leftType = MemberType.None;
MemberType rightType = MemberType.None;
var isConstant = mce.Arguments.First().NodeType == ExpressionType.Constant;
var left = CreateSqlElements(mce.Object, ref leftType,true);
var right = mce.Arguments[0].NodeType.IsIn(ExpressionType.Constant, ExpressionType.MemberAccess) ? CreateSqlElements(mce.Arguments[0], ref rightType, true) : Expression.Lambda(mce.Arguments[0]).Compile().DynamicInvoke().ObjToString();
if (right == "null")
{
right = "";
}
if (isConstant)
{
var oldLeft = AddParas(ref left, right);
if (isTure)
{
return string.Format("(" + this.ParSymbol + "{0} is null OR " + this.ParSymbol + "{0}='' )", left);
}
else
{
return string.Format("(" + this.ParSymbol + "{0} is not null AND " + this.ParSymbol + "{0}<>'' )", left);
}
}
else
{
if (isTure)
{
if (rightType == MemberType.Key)
{
return string.Format("({0} is null OR {0}='' )", right.ToSqlFilter());
}
else
{
return string.Format("('{0}' is null OR '{0}'='' )", right.ToSqlFilter());
}
}
else
{
if (rightType == MemberType.Key)
{
return string.Format("({0} is not null AND {0}<>'' )", right.ToSqlFilter());
}
else
{
return string.Format("('{0}' is not null AND '{0}'<>'' )", right.ToSqlFilter());
}
}
}
}
/// <summary>
/// 参数函数
/// </summary>
/// <param name="methodName"></param>
/// <param name="mce"></param>
/// <param name="type"></param>
/// <returns></returns>
private string ParMethodTo(string methodName, MethodCallExpression mce, ref MemberType type)
{
//参数函数
MemberType rightType = MemberType.None;
object right =null;
if (mce.Arguments.IsValuable() && !methodName.IsIn("AddDays", "AddYears", "AddMonths"))
{
right = CreateSqlElements(mce.Arguments[0], ref rightType, true);
}
else {
right = CreateSqlElements(mce.Object, ref rightType, true);
}
Check.Exception(rightType != MemberType.Value, string.Format(ExpMethodError2, methodName));
string value = string.Empty;
if (mce.Arguments.IsValuable())
{
value = right.ToString();
}
else
{
value = MethodToString(methodName, mce, ref type); ;
}
if (methodName.IsIn("AddDays", "AddYears", "AddMonths"))
{
if (value.IsValuable())
{
var parValue = CreateSqlElements(mce.Arguments[0], ref rightType, true).ObjToInt();
switch (methodName)
{
case "AddDays": value = value.ObjToDate().AddDays(parValue).ObjToString(); break;
case "AddYears": value = value.ObjToDate().AddYears(parValue).ObjToString(); break;
case "AddMonths": value = value.ObjToDate().AddMonths(parValue).ObjToString(); break;
}
}
return value;
}
if (methodName == "ToDateTime" || methodName == "ObjToDate")
{
return Convert.ToDateTime(value).ToString();
}
else if (methodName.StartsWith("ToInt"))
{
return Convert.ToInt32(value).ToString();
}
else if (methodName.StartsWith("Trim"))
{
return (value.ObjToString()).Trim();
}
else if (methodName.StartsWith("ObjTo"))
{
return value;
}
else if (methodName == "ToLower") {
if (value == null) return value;
else
return value.ToLower();
}
else if (methodName == "ToUpper")
{
if (value == null) return value;
else
return value.ToUpper();
}
else
{
throw new SqlSugarException("不支持当前函数:" + methodName + "\r\n" + ResolveExpress.ExpToSqlError);
}
}
/// <summary>
/// 拉姆达ToString函数处理
/// </summary>
/// <param name="methodName"></param>
/// <param name="mce"></param>
/// <param name="type"></param>
/// <returns></returns>
private string MethodToString(string methodName, MethodCallExpression mce, ref MemberType type)
{
return CreateSqlElements(mce.Object, ref type,true);
}
}
}

View File

@@ -1,66 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SqlSugar
{
//局部类:解析用到的实体
internal partial class ResolveExpress
{
/// <summary>
/// 拉姆达成员类型
/// </summary>
public enum MemberType
{
None = 0,
Key = 1,
Value = 2
}
/// <summary>
/// 用来处理bool类型的实体
/// </summary>
public class ExpressBoolModel
{
/// <summary>
/// 唯一标识
/// </summary>
public Guid Key { get; set; }
/// <summary>
/// 数据类型
/// </summary>
public Type Type { get; set; }
/// <summary>
/// 原始值
/// </summary>
public string OldValue { get; set; }
/// <summary>
/// 处事后的值
/// </summary>
public string NewValue
{
get
{
if (Type == PubConst.BoolType)
{
return Convert.ToBoolean(OldValue) ? "1" : "0";
}
else
{
return OldValue.ToString();
}
}
}
/// <summary>
/// 处理后的运算对象
/// </summary>
public string ConditionalValue
{
get
{
return Convert.ToBoolean(OldValue) ? "(1=1)" : "(1=2)";
}
}
}
}
}

View File

@@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SqlSugar
{
//局部类:解析属性
internal partial class ResolveExpress
{
private string GetProMethod(string methodName, string value, bool isField)
{
switch (methodName)
{
case "Length":
return ProLength(value, isField);
default: throw new SqlSugarException(string.Format(ExpNoSupportAttExtMethod, methodName));
}
}
private string ProLength(string value, bool isField)
{
if (isField)
{
return string.Format("LEN({0})", this.SqlBuilder.GetTranslationColumnName(value));
}
else
{
return string.Format("{0}", value.ObjToString().Length);
}
}
}
}

View File

@@ -1,84 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
namespace SqlSugar
{
//局部类 解析字段名
internal partial class ResolveExpress
{
/// <summary>
/// 获取拉姆达表达式的字段值
/// </summary>
/// <param name="exp"></param>
/// <param name="db">数据库访问对象</param>
/// <returns></returns>
public string GetExpressionRightField(Expression exp, SqlSugarClient db)
{
DB = db;
string reval = "";
LambdaExpression lambda = exp as LambdaExpression;
var isConvet = lambda.Body.NodeType.IsIn(ExpressionType.Convert);
var isMember = lambda.Body.NodeType.IsIn(ExpressionType.MemberAccess);
if (!isConvet && !isMember)
{
throw new SqlSugarException(FileldErrorMessage);
}
try
{
if (isConvet)
{
var memberExpr =((UnaryExpression)lambda.Body).Operand as MemberExpression;
reval= memberExpr.Member.Name;
}
else//isMember
{
reval= (lambda.Body as MemberExpression).Member.Name;
}
}
catch (Exception)
{
throw new SqlSugarException(FileldErrorMessage);
}
return reval;
}
/// <summary>
/// 获取拉姆达表达式的字段值多个T模式
/// </summary>
/// <param name="exp"></param>
/// <param name="db">数据库访问对象</param>
/// <returns></returns>
public string GetExpressionRightFieldByNT(Expression exp, SqlSugarClient db)
{
DB = db;
string reval = "";
LambdaExpression lambda = exp as LambdaExpression;
var isConvet = lambda.Body.NodeType.IsIn(ExpressionType.Convert);
var isMember = lambda.Body.NodeType.IsIn(ExpressionType.MemberAccess);
if (!isConvet && !isMember)
{
throw new SqlSugarException(FileldErrorMessage);
}
try
{
if (isConvet)
{
var memberExpr = ((UnaryExpression)lambda.Body).Operand as MemberExpression;
reval= memberExpr.ToString();
}
else//isMember
{
reval= lambda.Body.ToString();
}
}
catch (Exception)
{
throw new SqlSugarException(FileldErrorMessage);
}
return reval;
}
}
}

View File

@@ -29,11 +29,9 @@ namespace SqlSugar
{
var sqlBuilder = context.SqlBuilder;
var items = sqlBuilder.LambadaQueryBuilder;
ResolveExpress resolveExpress = new ResolveExpress(context);
items.WhereIndex = items.WhereIndex + 100;
resolveExpress.ResolveExpression(expression);
this.AddPars(resolveExpress.Paras, context);
items.WhereInfos.Add(resolveExpress.SqlWhere);
ILambdaExpressions resolveExpress = new SqlServerExpressionContext(expression,type);
_Pars.AddRange(resolveExpress.Parameters);
items.WhereInfos.Add(resolveExpress.Result.ToString());
}
protected void Where<T>(string whereString, object whereObj, SqlSugarClient context) where T : class, new()

View File

@@ -9,12 +9,14 @@ using System.Threading.Tasks;
namespace SqlSugar
{
public partial class SqlServerExpressionContext : ExpressionContext
public partial class SqlServerExpressionContext : ExpressionContext, ILambdaExpressions
{
public SqlSugarClient Context { get; set; }
public SqlServerExpressionContext(Expression expression, ResolveExpressType resolveType) : base(expression, resolveType)
{
base.DbMehtods = new SqlServerMethod();
}
}
public partial class SqlServerMethod : DefaultDbMethod, IDbMethods
{

View File

@@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SqlSugar
{
public class SqlServerLambadaQueryBuilder: LambadaQueryBuilder
{
}
}

View File

@@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SqlSugar
{
public class SqlServerLambdaExpressions : LambdaExpressionsProvider
{
}
}

View File

@@ -1,13 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace SqlSugar
{
public partial interface ILambdaExpressions
{
SqlSugarClient Context { get; set; }
IDbMethods DbMehtods { get; set; }
Expression Expression { get; set; }
int Index { get; set; }
int ParameterIndex { get; set; }
List<SugarParameter> Parameters { get; set; }
ExpressionResult Result { get; set; }
string SqlParameterKeyWord { get; }
string GetaMppingColumnsName(string name);
string GetAsString(string fieldName, string fieldValue);
void Resolve();
}
}

View File

@@ -54,14 +54,6 @@
<Compile Include="Abstract\DbProvider\DbMaintenanceProvider.cs" />
<Compile Include="Abstract\DbProvider\DbProvider.cs" />
<Compile Include="Abstract\DbProvider\SugarMappingAttribute.cs" />
<Compile Include="Abstract\LambdaExpressionsProvider\LambdaExpressionsProvider.cs" />
<Compile Include="Abstract\LambdaExpressionsProvider\ResolveExpress\Constant.cs" />
<Compile Include="Abstract\LambdaExpressionsProvider\ResolveExpress\Expressions.cs" />
<Compile Include="Abstract\LambdaExpressionsProvider\ResolveExpress\Main.cs" />
<Compile Include="Abstract\LambdaExpressionsProvider\ResolveExpress\Method.cs" />
<Compile Include="Abstract\LambdaExpressionsProvider\ResolveExpress\Models.cs" />
<Compile Include="Abstract\LambdaExpressionsProvider\ResolveExpress\Property.cs" />
<Compile Include="Abstract\LambdaExpressionsProvider\ResolveExpress\ResolveFieldName.cs" />
<Compile Include="Abstract\QueryableProvider\QueryableAccessory.cs" />
<Compile Include="Abstract\QueryableProvider\QueryableProvider.cs" />
<Compile Include="Abstract\SqlableProvider.cs" />
@@ -89,9 +81,7 @@
<Compile Include="Databases\SqlServer\Db\DbFirst\SqlServerDbFirst.cs" />
<Compile Include="Databases\SqlServer\Db\SqlBuilder\SqlServerBuilder.cs" />
<Compile Include="Databases\SqlServer\Db\SqlBuilder\SqlServerDbMaintenance.cs" />
<Compile Include="Databases\SqlServer\Db\SqlBuilder\SqlServerLambadaQueryBuilder.cs" />
<Compile Include="Databases\SqlServer\Db\SqlServerDb.cs" />
<Compile Include="Databases\SqlServer\LambdaExpressions\SqlServerLambdaExpressions.cs" />
<Compile Include="Databases\SqlServer\Queryable\SqlServerQueryable.cs" />
<Compile Include="Databases\SqlServer\Sqlable\SqlServerSqlable.cs" />
<Compile Include="Entities\ConnectionConfig.cs" />
@@ -100,7 +90,7 @@
<Compile Include="ExpressionsToSql\Common\CommonTempDataType.cs" />
<Compile Include="ExpressionsToSql\Common\MethodCallExpressionModel.cs" />
<Compile Include="ExpressionsToSql\Method\DefaultDbMethod.cs" />
<Compile Include="Databases\SqlServer\LambdaExpressions\SqlServerExpressionContext.cs" />
<Compile Include="Databases\SqlServer\Db\SqlBuilder\SqlServerExpressionContext.cs" />
<Compile Include="ExpressionsToSql\Method\NBORM.cs" />
<Compile Include="ExpressionsToSql\Common\BinaryExpressionInfo.cs" />
<Compile Include="ExpressionsToSql\Common\ExpressionResult.cs" />