SqlSugar/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs

243 lines
11 KiB
C#
Raw Normal View History

2017-01-30 15:10:54 +08:00
using SqlSugar;
using System;
2017-01-07 21:54:51 +08:00
using System.Collections.Generic;
2017-06-14 00:20:41 +08:00
using System.Collections.ObjectModel;
2017-01-07 21:54:51 +08:00
using System.Linq;
using System.Linq.Expressions;
using System.Text;
namespace SqlSugar
{
2017-01-30 15:10:54 +08:00
public class MethodCallExpressionResolve : BaseResolve
2017-01-07 21:54:51 +08:00
{
2017-01-07 23:56:55 +08:00
public MethodCallExpressionResolve(ExpressionParameter parameter) : base(parameter)
2017-01-07 21:54:51 +08:00
{
2017-01-30 15:10:54 +08:00
var express = base.Expression as MethodCallExpression;
2017-01-31 20:13:22 +08:00
var isLeft = parameter.IsLeft;
2017-06-14 00:20:41 +08:00
var isValidNativeMethod =
express.Method.Name.IsIn(
"ToString", "ToInt32", "ToInt64",
"Length", "Replace", "Substring",
"Contains", "EndsWith", "StartsWith",
"HasValue", "Trim", "Equals",
"ToLower", "ToUpper");
if (isValidNativeMethod)
{
NativeExtensionMethod(parameter, express, isLeft);
}
else
{
SqlFuncMethod(parameter, express, isLeft);
}
}
private void SqlFuncMethod(ExpressionParameter parameter, MethodCallExpression express, bool? isLeft)
{
2017-01-30 15:10:54 +08:00
CheckMethod(express);
var method = express.Method;
string name = method.Name;
2017-06-14 00:20:41 +08:00
var args = express.Arguments.Cast<Expression>().ToList();
2017-01-30 15:10:54 +08:00
MethodCallExpressionModel model = new MethodCallExpressionModel();
model.Args = new List<MethodCallExpressionArgs>();
switch (this.Context.ResolveType)
{
case ResolveExpressType.WhereSingle:
case ResolveExpressType.WhereMultiple:
2017-06-12 17:47:25 +08:00
Where(parameter, isLeft, name, args, model);
2017-01-30 15:10:54 +08:00
break;
case ResolveExpressType.SelectSingle:
case ResolveExpressType.SelectMultiple:
2017-05-24 20:35:23 +08:00
case ResolveExpressType.Update:
2017-06-12 17:47:25 +08:00
Select(parameter, isLeft, name, args, model);
2017-04-30 16:11:51 +08:00
break;
2017-01-30 15:10:54 +08:00
case ResolveExpressType.FieldSingle:
case ResolveExpressType.FieldMultiple:
default:
break;
}
}
2017-06-14 00:20:41 +08:00
private void NativeExtensionMethod(ExpressionParameter parameter, MethodCallExpression express, bool? isLeft)
{
var method = express.Method;
string name = method.Name;
var args = express.Arguments.Cast<Expression>().ToList();
MethodCallExpressionModel model = new MethodCallExpressionModel();
model.Args = new List<MethodCallExpressionArgs>();
switch (this.Context.ResolveType)
{
case ResolveExpressType.WhereSingle:
case ResolveExpressType.WhereMultiple:
if (express.Object != null)
args.Insert(0,express.Object);
Where(parameter, isLeft, name, args, model);
break;
case ResolveExpressType.SelectSingle:
case ResolveExpressType.SelectMultiple:
case ResolveExpressType.Update:
if (express.Object != null)
args.Insert(0, express.Object);
Select(parameter, isLeft, name, args, model);
break;
case ResolveExpressType.FieldSingle:
case ResolveExpressType.FieldMultiple:
default:
break;
}
}
private void Select(ExpressionParameter parameter, bool? isLeft, string name, IEnumerable<Expression> args, MethodCallExpressionModel model)
2017-04-30 16:11:51 +08:00
{
foreach (var item in args)
{
2017-06-12 17:47:25 +08:00
var isBinaryExpression = item is BinaryExpression || item is MethodCallExpression;
if (isBinaryExpression)
2017-04-30 16:11:51 +08:00
{
2017-06-12 22:59:34 +08:00
model.Args.Add(GetMethodCallArgs(parameter, item));
2017-04-30 16:11:51 +08:00
}
2017-06-12 17:47:25 +08:00
else
2017-04-30 16:11:51 +08:00
{
2017-06-12 17:47:25 +08:00
Default(parameter, model, item);
2017-04-30 16:11:51 +08:00
}
}
parameter.BaseParameter.CommonTempData = GetMdthodValue(name, model);
}
2017-06-14 00:20:41 +08:00
private void Where(ExpressionParameter parameter, bool? isLeft, string name, IEnumerable<Expression> args, MethodCallExpressionModel model)
2017-04-30 16:11:51 +08:00
{
foreach (var item in args)
{
2017-06-14 00:20:41 +08:00
var isBinaryExpression = item is BinaryExpression || item is MethodCallExpression;
2017-06-12 17:47:25 +08:00
if (isBinaryExpression)
2017-04-30 16:11:51 +08:00
{
2017-06-12 22:59:34 +08:00
model.Args.Add(GetMethodCallArgs(parameter, item));
2017-04-30 16:11:51 +08:00
}
2017-06-12 17:47:25 +08:00
else
2017-04-30 16:11:51 +08:00
{
2017-06-12 17:47:25 +08:00
Default(parameter, model, item);
2017-04-30 16:11:51 +08:00
}
}
var methodValue = GetMdthodValue(name, model);
base.AppendValue(parameter, isLeft, methodValue);
}
2017-06-12 17:47:25 +08:00
private void Default(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item)
{
parameter.CommonTempData = CommonTempDataType.Result;
base.Expression = item;
base.Start();
var methodCallExpressionArgs = new MethodCallExpressionArgs()
{
IsMember = parameter.ChildExpression is MemberExpression,
MemberName = parameter.CommonTempData
};
if (methodCallExpressionArgs.IsMember && parameter.ChildExpression != null && parameter.ChildExpression.ToString() == "DateTime.Now")
{
methodCallExpressionArgs.IsMember = false;
}
var value = methodCallExpressionArgs.MemberName;
if (methodCallExpressionArgs.IsMember)
{
var childExpression = parameter.ChildExpression as MemberExpression;
if (childExpression.Expression != null && childExpression.Expression is ConstantExpression)
{
methodCallExpressionArgs.IsMember = false;
}
}
if (methodCallExpressionArgs.IsMember == false)
{
var parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.MethodConst + this.Context.ParameterIndex;
this.Context.ParameterIndex++;
methodCallExpressionArgs.MemberName = parameterName;
methodCallExpressionArgs.MemberValue = value;
this.Context.Parameters.Add(new SugarParameter(parameterName, value));
}
model.Args.Add(methodCallExpressionArgs);
}
2017-01-31 20:13:22 +08:00
2017-01-30 15:10:54 +08:00
private object GetMdthodValue(string name, MethodCallExpressionModel model)
{
switch (name)
{
2017-06-12 17:47:25 +08:00
case "IIF":
return this.Context.DbMehtods.IIF(model);
2017-06-04 09:27:41 +08:00
case "HasNumber":
return this.Context.DbMehtods.HasNumber(model);
case "HasValue":
return this.Context.DbMehtods.HasValue(model);
2017-01-30 15:10:54 +08:00
case "IsNullOrEmpty":
2017-01-30 16:42:33 +08:00
return this.Context.DbMehtods.IsNullOrEmpty(model);
2017-01-30 18:53:06 +08:00
case "ToLower":
return this.Context.DbMehtods.ToLower(model);
2017-01-30 21:54:23 +08:00
case "ToUpper":
return this.Context.DbMehtods.ToUpper(model);
2017-01-30 22:05:08 +08:00
case "Trim":
return this.Context.DbMehtods.Trim(model);
2017-01-31 20:39:57 +08:00
case "Contains":
2017-05-31 01:29:25 +08:00
return this.Context.DbMehtods.Contains(model);
2017-04-30 14:31:07 +08:00
case "ContainsArray":
2017-05-31 01:29:25 +08:00
var result = this.Context.DbMehtods.ContainsArray(model);
this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[0].MemberName.ObjToString());
return result;
2017-04-29 22:51:41 +08:00
case "Equals":
return this.Context.DbMehtods.Equals(model);
case "DateIsSame":
if (model.Args.Count == 2)
return this.Context.DbMehtods.DateIsSameDay(model);
else
return this.Context.DbMehtods.DateIsSameByType(model);
case "DateAdd":
if (model.Args.Count == 2)
return this.Context.DbMehtods.DateAddDay(model);
else
return this.Context.DbMehtods.DateAddByType(model);
2017-04-29 23:37:49 +08:00
case "DateValue":
return this.Context.DbMehtods.DateValue(model);
2017-04-29 23:08:14 +08:00
case "Between":
return this.Context.DbMehtods.Between(model);
2017-04-29 23:20:31 +08:00
case "StartsWith":
return this.Context.DbMehtods.StartsWith(model);
case "EndsWith":
return this.Context.DbMehtods.EndsWith(model);
2017-04-30 12:05:05 +08:00
case "ToInt32":
2017-05-31 01:29:25 +08:00
return this.Context.DbMehtods.ToInt32(model);
2017-04-30 12:05:05 +08:00
case "ToInt64":
return this.Context.DbMehtods.ToInt64(model);
case "ToDate":
return this.Context.DbMehtods.ToDate(model);
case "ToString":
return this.Context.DbMehtods.ToString(model);
case "ToDecimal":
return this.Context.DbMehtods.ToDecimal(model);
case "ToGuid":
return this.Context.DbMehtods.ToGuid(model);
case "ToDouble":
return this.Context.DbMehtods.ToDouble(model);
case "ToBool":
return this.Context.DbMehtods.ToBool(model);
case "Substring":
return this.Context.DbMehtods.Substring(model);
case "Replace":
return this.Context.DbMehtods.Replace(model);
case "Length":
return this.Context.DbMehtods.Length(model);
2017-04-30 16:11:51 +08:00
case "AggregateSum":
return this.Context.DbMehtods.AggregateSum(model);
case "AggregateAvg":
return this.Context.DbMehtods.AggregateAvg(model);
case "AggregateMin":
return this.Context.DbMehtods.AggregateMin(model);
case "AggregateMax":
return this.Context.DbMehtods.AggregateMax(model);
case "AggregateCount":
return this.Context.DbMehtods.AggregateCount(model);
2017-01-30 15:10:54 +08:00
default:
break;
}
return null;
}
2017-05-25 01:40:15 +08:00
private void CheckMethod(MethodCallExpression expression)
2017-01-30 15:10:54 +08:00
{
2017-05-31 15:42:21 +08:00
Check.Exception(expression.Method.ReflectedType.FullName != ExpressionConst.SqlFuncFullName, ExpressionErrorMessage.MethodError);
2017-01-07 21:54:51 +08:00
}
}
}