Browse Source

Support method nesting

pull/12/MERGE
sunkaixuan 8 years ago
parent
commit
93192405ce
  1. 48
      SqlServerTest/Program.cs
  2. 72
      SqlServerTest/UnitTest/ExpressionTest/Method.cs
  3. 7
      SqlSugar/ExpressionsToSql/ExpressionContext.cs
  4. 23
      SqlSugar/ExpressionsToSql/Method/DefaultDbMethod.cs
  5. 1
      SqlSugar/ExpressionsToSql/Method/IDbMethods.cs
  6. 2
      SqlSugar/ExpressionsToSql/Method/SqlFunc.cs
  7. 118
      SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs

48
SqlServerTest/Program.cs

@ -17,31 +17,31 @@ namespace OrmTest
{
static void Main(string[] args)
{
///***Unit Test***/
//new Field(1).Init();
//new Where(1).Init();
//new Method(1).Init();
//new JoinQuery(1).Init();
//new SingleQuery(1).Init();
//new SelectQuery(1).Init();
//new AutoClose(1).Init();
//new Insert(1).Init();
//new Delete(1).Init();
//new Update(1).Init();
//new Mapping(1).Init();
//new DataTest(1).Init();
///***Performance Test***/
//new SqlSugarPerformance(100).Select();
/***Unit Test***/
new Field(1).Init();
new Where(1).Init();
new Method(1).Init();
new JoinQuery(1).Init();
new SingleQuery(1).Init();
new SelectQuery(1).Init();
new AutoClose(1).Init();
new Insert(1).Init();
new Delete(1).Init();
new Update(1).Init();
new Mapping(1).Init();
new DataTest(1).Init();
/***Performance Test***/
new SqlSugarPerformance(100).Select();
///***Demo***/
//OrmTest.Demo.Query.Init();
//OrmTest.Demo.Insert.Init();
//OrmTest.Demo.Delete.Init();
//OrmTest.Demo.Update.Init();
//OrmTest.Demo.DbFirst.Init();
//OrmTest.Demo.JoinSql.Init();
//OrmTest.Demo.Filter.Init();
//OrmTest.Demo.MaterSlave.Init();
/***Demo***/
OrmTest.Demo.Query.Init();
OrmTest.Demo.Insert.Init();
OrmTest.Demo.Delete.Init();
OrmTest.Demo.Update.Init();
OrmTest.Demo.DbFirst.Init();
OrmTest.Demo.JoinSql.Init();
OrmTest.Demo.Filter.Init();
OrmTest.Demo.MaterSlave.Init();
OrmTest.Demo.ComplexModel.Init();
}
}

72
SqlServerTest/UnitTest/ExpressionTest/Method.cs

@ -21,6 +21,8 @@ namespace OrmTest.UnitTest
base.Begin();
for (int i = 0; i < base.Count; i++)
{
IIF();
IIF2();
#region StringIsNullOrEmpty
HasValue();
HasNumber();
@ -62,7 +64,7 @@ namespace OrmTest.UnitTest
private void Length()
{
Expression<Func<Student, bool>> exp = it => SqlFunc.Length("aaaa") >1;
Expression<Func<Student, bool>> exp = it => SqlFunc.Length("aaaa") > 1;
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
@ -75,7 +77,7 @@ namespace OrmTest.UnitTest
private void Replace()
{
var x2 = Guid.NewGuid();
Expression<Func<Student, bool>> exp = it => SqlFunc.Replace("aaaa","a", "1") == "a";
Expression<Func<Student, bool>> exp = it => SqlFunc.Replace("aaaa", "a", "1") == "a";
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
@ -88,7 +90,7 @@ namespace OrmTest.UnitTest
private void Substring()
{
var x2 = Guid.NewGuid();
Expression<Func<Student, bool>> exp = it => SqlFunc.Substring("aaaa",0,2) == "a";
Expression<Func<Student, bool>> exp = it => SqlFunc.Substring("aaaa", 0, 2) == "a";
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
@ -192,7 +194,7 @@ namespace OrmTest.UnitTest
private void ToInt32()
{
var x2 = DateTime.Now;
Expression<Func<Student, bool>> exp = it => SqlFunc.ToInt32("3")== 1;
Expression<Func<Student, bool>> exp = it => SqlFunc.ToInt32("3") == 1;
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
@ -205,7 +207,7 @@ namespace OrmTest.UnitTest
private void DateValue()
{
var x2 = DateTime.Now;
Expression<Func<Student, bool>> exp = it => SqlFunc.DateValue(x2,DateType.Year)==1;
Expression<Func<Student, bool>> exp = it => SqlFunc.DateValue(x2, DateType.Year) == 1;
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
@ -239,7 +241,7 @@ namespace OrmTest.UnitTest
}
private void Between()
{
Expression<Func<Student, bool>> exp = it => SqlFunc.Between(it.Name,1, 2);
Expression<Func<Student, bool>> exp = it => SqlFunc.Between(it.Name, 1, 2);
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
@ -252,7 +254,7 @@ namespace OrmTest.UnitTest
private void DateAddByType()
{
var x2 = DateTime.Now;
Expression<Func<Student, bool>> exp = it => SqlFunc.DateAdd(x2, 11, DateType.Millisecond)==x2;
Expression<Func<Student, bool>> exp = it => SqlFunc.DateAdd(x2, 11, DateType.Millisecond) == x2;
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
@ -265,7 +267,7 @@ namespace OrmTest.UnitTest
private void DateAddDay()
{
var x2 = DateTime.Now;
Expression<Func<Student, bool>> exp = it => SqlFunc.DateAdd(x2, 1)==x2;
Expression<Func<Student, bool>> exp = it => SqlFunc.DateAdd(x2, 1) == x2;
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
@ -278,7 +280,7 @@ namespace OrmTest.UnitTest
private void DateIsSameByType()
{
var x2 = DateTime.Now;
Expression<Func<Student, bool>> exp = it => SqlFunc.DateIsSame(x2,x2, DateType.Millisecond);
Expression<Func<Student, bool>> exp = it => SqlFunc.DateIsSame(x2, x2, DateType.Millisecond);
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
@ -291,7 +293,7 @@ namespace OrmTest.UnitTest
private void DateIsSameByDay()
{
var x2 = DateTime.Now;
Expression<Func<Student, bool>> exp = it => SqlFunc.DateIsSame(x2,x2);
Expression<Func<Student, bool>> exp = it => SqlFunc.DateIsSame(x2, x2);
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
@ -313,7 +315,7 @@ namespace OrmTest.UnitTest
}, "Equals1 error");
Expression<Func<Student, bool>> exp2 = it => SqlFunc.Equals("a",it.Name);
Expression<Func<Student, bool>> exp2 = it => SqlFunc.Equals("a", it.Name);
SqlServerExpressionContext expContext2 = new SqlServerExpressionContext();
expContext2.Resolve(exp2, ResolveExpressType.WhereSingle);
var value2 = expContext2.Result.GetString();
@ -358,18 +360,18 @@ namespace OrmTest.UnitTest
private void ContainsArray()
{
string[] array = new string[] { "1","2"};
string[] array = new string[] { "1", "2" };
Expression<Func<Student, bool>> exp = it => SqlFunc.ContainsArray(array, it.Name);
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
var pars = expContext.Parameters;
base.Check(value, null, " ([Name] IN ('1','2')) ",null, "Contains2 error");
base.Check(value, null, " ([Name] IN ('1','2')) ", null, "Contains2 error");
}
private void Trim()
{
Expression<Func<Student, bool>> exp = it =>SqlFunc.Trim(" a")==it.Name;
Expression<Func<Student, bool>> exp = it => SqlFunc.Trim(" a") == it.Name;
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
@ -381,7 +383,7 @@ namespace OrmTest.UnitTest
private void ToUpper()
{
Expression<Func<Student, bool>> exp = it =>"a"== SqlFunc.ToUpper(it.Id) ;
Expression<Func<Student, bool>> exp = it => "a" == SqlFunc.ToUpper(it.Id);
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
@ -455,7 +457,7 @@ namespace OrmTest.UnitTest
private void StringIsNullOrEmpty5()
{
WhereConst.name = "xx";
Expression<Func<Student, bool>> exp =it=>!SqlFunc.IsNullOrEmpty(WhereConst.name);;
Expression<Func<Student, bool>> exp = it => !SqlFunc.IsNullOrEmpty(WhereConst.name); ;
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
@ -473,8 +475,9 @@ namespace OrmTest.UnitTest
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
var pars = expContext.Parameters;
base.Check(value, pars, "( [Name]<>'' AND [Name] IS NOT NULL )", new List<SugarParameter>() {
base.Check(value, pars, "( [Name]<>'' AND [Name] IS NOT NULL )", new List<SugarParameter>()
{
}, "HasValue error");
}
@ -485,11 +488,42 @@ namespace OrmTest.UnitTest
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
var pars = expContext.Parameters;
base.Check(value, pars, "( [Id]>0 AND [Id] IS NOT NULL )", new List<SugarParameter>() {
base.Check(value, pars, "( [Id]>0 AND [Id] IS NOT NULL )", new List<SugarParameter>()
{
}, "HasNumber error");
}
private void IIF()
{
Expression<Func<Student, bool>> exp = it => SqlFunc.IIF(it.Id == 1, 1, 2);
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
var pars = expContext.Parameters;
base.Check(value, pars, "( CASE WHEN ( [Id] = @Id1 ) THEN @MethodConst2 ELSE @MethodConst3 END )", new List<SugarParameter>()
{
new SugarParameter("@Id1",1),
new SugarParameter("@MethodConst2",1),
new SugarParameter("@MethodConst3",2)
}, "IIF error");
}
private void IIF2()
{
Expression<Func<Student, bool>> exp = it => SqlFunc.IIF(SqlFunc.Contains(it.Name,"a"), 1, 2);
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
var pars = expContext.Parameters;
base.Check(value, pars, "( CASE WHEN ([Name] like '%'+@MethodConst1+'%') THEN @MethodConst2 ELSE @MethodConst3 END )", new List<SugarParameter>()
{
new SugarParameter("@MethodConst1","a"),
new SugarParameter("@MethodConst2",1),
new SugarParameter("@MethodConst3",2)
}, "IIF error");
}
}
}

7
SqlSugar/ExpressionsToSql/ExpressionContext.cs

@ -164,6 +164,13 @@ namespace SqlSugar
base._Result = null;
base._Parameters = new List<SugarParameter>();
}
public ExpressionContext GetCopyContext()
{
ExpressionContext copyContext = (ExpressionContext)Activator.CreateInstance(this.GetType(), true);
copyContext.Index = this.Index + 1;
copyContext.ParameterIndex = this.ParameterIndex + 1;
return copyContext;
}
#endregion
}
}

23
SqlSugar/ExpressionsToSql/Method/DefaultDbMethod.cs

@ -8,6 +8,14 @@ namespace SqlSugar
{
public abstract partial class DefaultDbMethod : IDbMethods
{
public virtual string IIF(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter2 = model.Args[1];
var parameter3 = model.Args[2];
return string.Format("( CASE WHEN {0} THEN {1} ELSE {2} END )", parameter.MemberName, parameter2.MemberName, parameter3.MemberName);
}
public virtual string IsNullOrEmpty(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
@ -54,7 +62,7 @@ namespace SqlSugar
public virtual string ContainsArray(MethodCallExpressionModel model)
{
var inValueIEnumerable = (IEnumerable)model.Args[0].MemberValue;
List<object> inValues = new List<object>();
List<object> inValues = new List<object>();
if (inValueIEnumerable != null)
{
foreach (var item in inValueIEnumerable)
@ -68,10 +76,11 @@ namespace SqlSugar
{
inValueString = inValues.ToArray().ToJoinSqlInVals();
}
else {
return " (1=2) ";
else
{
return " (1=2) ";
}
return string.Format(" ({0} IN ({1})) ", value,inValueString);
return string.Format(" ({0} IN ({1})) ", value, inValueString);
}
public string Equals(MethodCallExpressionModel model)
@ -93,7 +102,7 @@ namespace SqlSugar
var parameter = model.Args[0];
var parameter2 = model.Args[1];
var parameter3 = model.Args[2];
return string.Format(" (DATEDIFF({2},{0},{1})=0) ", parameter.MemberName, parameter2.MemberName, parameter3.MemberName);
return string.Format(" (DATEDIFF({2},{0},{1})=0) ", parameter.MemberName, parameter2.MemberName, parameter3.MemberName);
}
public string DateAddByType(MethodCallExpressionModel model)
@ -108,7 +117,7 @@ namespace SqlSugar
{
var parameter = model.Args[0];
var parameter2 = model.Args[1];
return string.Format(" (DATEADD(day,{1},{0})) ", parameter.MemberName, parameter2.MemberName);
return string.Format(" (DATEADD(day,{1},{0})) ", parameter.MemberName, parameter2.MemberName);
}
public string Between(MethodCallExpressionModel model)
@ -192,7 +201,7 @@ namespace SqlSugar
var parameter = model.Args[0];
var parameter2 = model.Args[1];
var parameter3 = model.Args[2];
return string.Format("SUBSTRING({0},1 + {1},{2})", parameter.MemberName,parameter2.MemberName, parameter3.MemberName);
return string.Format("SUBSTRING({0},1 + {1},{2})", parameter.MemberName, parameter2.MemberName, parameter3.MemberName);
}
public string Length(MethodCallExpressionModel model)

1
SqlSugar/ExpressionsToSql/Method/IDbMethods.cs

@ -11,6 +11,7 @@ namespace SqlSugar
{
public interface IDbMethods
{
string IIF(MethodCallExpressionModel model);
string HasNumber(MethodCallExpressionModel model);
string HasValue(MethodCallExpressionModel model);
string IsNullOrEmpty(MethodCallExpressionModel model);

2
SqlSugar/ExpressionsToSql/Method/SqlFunc.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
@ -65,6 +66,7 @@ namespace SqlSugar
public static DateTime DateAdd(DateTime date, int addValue) { throw new NotSupportedException("This method is not supported by the current parameter"); }
public static int DateValue(DateTime date, DateType dataType) { throw new NotSupportedException("This method is not supported by the current parameter"); }
public static bool Between(object value, object start, object end) { throw new NotSupportedException("This method is not supported by the current parameter"); }
public static bool IIF(bool Expression, object thenValue, object elseValue) { throw new NotSupportedException("This method is not supported by the current parameter"); }
public static int ToInt32(object value) { return value.ObjToInt(); }
public static long ToInt64(object value) { return Convert.ToInt64(value); }
public static DateTime ToDate(object value) { return value.ObjToDate(); }

118
SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs

@ -22,12 +22,12 @@ namespace SqlSugar
{
case ResolveExpressType.WhereSingle:
case ResolveExpressType.WhereMultiple:
WhereMethod(parameter, isLeft, name, args, model);
Where(parameter, isLeft, name, args, model);
break;
case ResolveExpressType.SelectSingle:
case ResolveExpressType.SelectMultiple:
case ResolveExpressType.Update:
SelectMethod(parameter, isLeft, name, args, model);
Select(parameter, isLeft, name, args, model);
break;
case ResolveExpressType.FieldSingle:
case ResolveExpressType.FieldMultiple:
@ -35,82 +35,96 @@ namespace SqlSugar
break;
}
}
private void SelectMethod(ExpressionParameter parameter, bool? isLeft, string name, System.Collections.ObjectModel.ReadOnlyCollection<Expression> args, MethodCallExpressionModel model)
private void Select(ExpressionParameter parameter, bool? isLeft, string name, System.Collections.ObjectModel.ReadOnlyCollection<Expression> args, MethodCallExpressionModel model)
{
foreach (var item in args)
{
parameter.CommonTempData = CommonTempDataType.Result;
base.Expression = item;
base.Start();
var methodCallExpressionArgs = new MethodCallExpressionArgs()
var isBinaryExpression = item is BinaryExpression || item is MethodCallExpression;
if (isBinaryExpression)
{
IsMember = parameter.ChildExpression is MemberExpression,
MemberName = parameter.CommonTempData
};
var value = methodCallExpressionArgs.MemberName;
if (methodCallExpressionArgs.IsMember)
{
var childExpression = parameter.ChildExpression as MemberExpression;
if (childExpression.Expression != null && childExpression.Expression is ConstantExpression)
{
methodCallExpressionArgs.IsMember = false;
}
Binary(parameter, model, item);
}
if (methodCallExpressionArgs.IsMember == false)
else
{
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));
Default(parameter, model, item);
}
model.Args.Add(methodCallExpressionArgs);
}
parameter.BaseParameter.CommonTempData = GetMdthodValue(name, model);
}
private void WhereMethod(ExpressionParameter parameter, bool? isLeft, string name, System.Collections.ObjectModel.ReadOnlyCollection<Expression> args, MethodCallExpressionModel model)
private void Where(ExpressionParameter parameter, bool? isLeft, string name, System.Collections.ObjectModel.ReadOnlyCollection<Expression> args, MethodCallExpressionModel model)
{
foreach (var item in args)
{
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 isBinaryExpression = item is BinaryExpression||item is MethodCallExpression;
if (isBinaryExpression)
{
var childExpression = parameter.ChildExpression as MemberExpression;
if (childExpression.Expression != null && childExpression.Expression is ConstantExpression)
{
methodCallExpressionArgs.IsMember = false;
}
Binary(parameter, model, item);
}
if (methodCallExpressionArgs.IsMember == false)
else
{
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));
Default(parameter, model, item);
}
model.Args.Add(methodCallExpressionArgs);
}
var methodValue = GetMdthodValue(name, model);
base.AppendValue(parameter, isLeft, methodValue);
}
private void Binary(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item)
{
var newContext = this.Context.GetCopyContext();
newContext.Resolve(item, this.Context.ResolveType);
this.Context.Index = newContext.Index ;
this.Context.ParameterIndex = newContext.ParameterIndex ;
if (newContext.Parameters.IsValuable())
{
this.Context.Parameters.AddRange(newContext.Parameters);
}
var methodCallExpressionArgs = new MethodCallExpressionArgs()
{
IsMember = true,
MemberName = newContext.Result.GetResultString()
};
model.Args.Add(methodCallExpressionArgs);
}
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);
}
private object GetMdthodValue(string name, MethodCallExpressionModel model)
{
switch (name)
{
case "IIF":
return this.Context.DbMehtods.IIF(model);
case "HasNumber":
return this.Context.DbMehtods.HasNumber(model);
case "HasValue":

Loading…
Cancel
Save