- 优化 WhereDynamicFilter Value 支持数组或字符串;

This commit is contained in:
28810 2020-06-01 22:36:38 +08:00
parent 875c109144
commit 1f02eb6a13
4 changed files with 36 additions and 24 deletions

View File

@ -486,14 +486,5 @@
<param name="that"></param> <param name="that"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
<summary>
批量注入 Repository可以参考代码自行调整
</summary>
<param name="services"></param>
<param name="globalDataFilter"></param>
<param name="assemblies"></param>
<returns></returns>
</member>
</members> </members>
</doc> </doc>

View File

@ -1990,34 +1990,34 @@ WHERE (((a.""Code"") LIKE '%val1%' AND (a.""Name"") LIKE 'val2%' OR (a.""Name"")
{ {
""Field"" : ""CreateTime"", ""Field"" : ""CreateTime"",
""Operator"" : ""DateRange"", ""Operator"" : ""DateRange"",
""Value"" : ""2010-10-10,2010-11-10"" ""Value"" : [""2010-10-10"", ""2010-11-10""]
}, },
{ {
""Field"" : ""CreateTime"", ""Field"" : ""CreateTime"",
""Operator"" : ""DateRange"", ""Operator"" : ""DateRange"",
""Value"" : ""2010-10-10,2010-11"" ""Value"" : ""2010-10,2010-11""
}, },
{ {
""Field"" : ""CreateTime"", ""Field"" : ""CreateTime"",
""Operator"" : ""DateRange"", ""Operator"" : ""DateRange"",
""Value"" : ""2010-10-10,2010"" ""Value"" : ""2010,2010""
}, },
{ {
""Field"" : ""CreateTime"", ""Field"" : ""CreateTime"",
""Operator"" : ""DateRange"", ""Operator"" : ""DateRange"",
""Value"" : ""2010-10-10,2010-11-10 11"" ""Value"" : ""2010-10-10 11,2010-11-10 11""
}, },
{ {
""Field"" : ""CreateTime"", ""Field"" : ""CreateTime"",
""Operator"" : ""DateRange"", ""Operator"" : ""DateRange"",
""Value"" : ""2010-10-10,2010-11-10 11:20"" ""Value"" : ""2010-10-10 11:20,2010-11-10 11:20""
}, },
] ]
} }
")).ToSql(); ")).ToSql();
Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""CreateTime"", a.""testint"", a.""ParentCode"" Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""CreateTime"", a.""testint"", a.""ParentCode""
FROM ""D_District"" a FROM ""D_District"" a
WHERE ((a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-11-11 00:00:00' OR a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-12-01 00:00:00' OR a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2011-01-01 00:00:00' OR a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-11-10 12:00:00' OR a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-11-10 11:21:00'))", sql); WHERE ((a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-11-11 00:00:00' OR a.""CreateTime"" >= '2010-10-01 00:00:00' AND a.""CreateTime"" < '2010-12-01 00:00:00' OR a.""CreateTime"" >= '2010-01-01 00:00:00' AND a.""CreateTime"" < '2011-01-01 00:00:00' OR a.""CreateTime"" >= '2010-10-10 11:00:00' AND a.""CreateTime"" < '2010-11-10 12:00:00' OR a.""CreateTime"" >= '2010-10-10 11:20:00' AND a.""CreateTime"" < '2010-11-10 11:21:00'))", sql);
sql = fsql.Select<VM_District_Parent>().WhereDynamicFilter(JsonConvert.DeserializeObject<DynamicFilterInfo>(@" sql = fsql.Select<VM_District_Parent>().WhereDynamicFilter(JsonConvert.DeserializeObject<DynamicFilterInfo>(@"
{ {

View File

@ -1,5 +1,6 @@
using FreeSql.Internal.Model; using FreeSql.Internal.Model;
using System; using System;
using System.Collections;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
@ -1102,34 +1103,54 @@ namespace FreeSql.Internal.CommonProvider
case DynamicFilterOperator.LessThan: exp = Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; case DynamicFilterOperator.LessThan: exp = Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break;
case DynamicFilterOperator.LessThanOrEqual: exp = Expression.LessThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; case DynamicFilterOperator.LessThanOrEqual: exp = Expression.LessThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break;
case DynamicFilterOperator.Range: case DynamicFilterOperator.Range:
var fiValueRangeArray = fi.Value.Split(','); var fiValueRangeArray = getFiListValue();
if (fiValueRangeArray.Length != 2) throw new ArgumentException($"Range 要求 Value 应该逗号分割,并且长度为 2"); if (fiValueRangeArray.Length != 2) throw new ArgumentException($"Range 要求 Value 应该逗号分割,并且长度为 2");
exp = Expression.AndAlso( exp = Expression.AndAlso(
Expression.GreaterThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueRangeArray[0]), exp.Type)), Expression.GreaterThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueRangeArray[0]), exp.Type)),
Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueRangeArray[1]), exp.Type))); Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueRangeArray[1]), exp.Type)));
break; break;
case DynamicFilterOperator.DateRange: case DynamicFilterOperator.DateRange:
var fiValueDateRangeArray = fi.Value.Split(','); var fiValueDateRangeArray = getFiListValue();
if (fiValueDateRangeArray.Length != 2) throw new ArgumentException($"DateRange 要求 Value 应该逗号分割,并且长度为 2"); if (fiValueDateRangeArray?.Length != 2) throw new ArgumentException($"DateRange 要求 Value 应该逗号分割,并且长度为 2");
if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse(fiValueDateRangeArray[1]).AddDays(1).ToString("yyyy-MM-dd HH:mm:ss"); if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse(fiValueDateRangeArray[1]).AddDays(1).ToString("yyyy-MM-dd HH:mm:ss");
else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}-01").AddMonths(1).ToString("yyyy-MM-dd HH:mm:ss"); else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}-01").AddMonths(1).ToString("yyyy-MM-dd HH:mm:ss");
else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}-01-01").AddYears(1).ToString("yyyy-MM-dd HH:mm:ss"); else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}-01-01").AddYears(1).ToString("yyyy-MM-dd HH:mm:ss");
else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d? \d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}:00:00").AddHours(1).ToString("yyyy-MM-dd HH:mm:ss"); else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d? \d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}:00:00").AddHours(1).ToString("yyyy-MM-dd HH:mm:ss");
else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d? \d\d?:\d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}:00").AddMinutes(1).ToString("yyyy-MM-dd HH:mm:ss"); else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d? \d\d?:\d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}:00").AddMinutes(1).ToString("yyyy-MM-dd HH:mm:ss");
else throw new ArgumentException($"DateRange 要求 Value[1] 格式必须为yyyy、yyyy-MM、yyyy-MM-dd、yyyy-MM-dd HH、yyyy、yyyy-MM-dd HH:mm"); else throw new ArgumentException($"DateRange 要求 Value[1] 格式必须为yyyy、yyyy-MM、yyyy-MM-dd、yyyy-MM-dd HH、yyyy、yyyy-MM-dd HH:mm");
if (Regex.IsMatch(fiValueDateRangeArray[0], @"^\d\d\d\d[\-/]\d\d?$")) fiValueDateRangeArray[0] = DateTime.Parse($"{fiValueDateRangeArray[0]}-01").ToString("yyyy-MM-dd HH:mm:ss");
else if (Regex.IsMatch(fiValueDateRangeArray[0], @"^\d\d\d\d$")) fiValueDateRangeArray[0] = DateTime.Parse($"{fiValueDateRangeArray[0]}-01-01").ToString("yyyy-MM-dd HH:mm:ss");
else if (Regex.IsMatch(fiValueDateRangeArray[0], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d? \d\d?$")) fiValueDateRangeArray[0] = DateTime.Parse($"{fiValueDateRangeArray[0]}:00:00").ToString("yyyy-MM-dd HH:mm:ss");
else if (Regex.IsMatch(fiValueDateRangeArray[0], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d? \d\d?:\d\d?$")) fiValueDateRangeArray[0] = DateTime.Parse($"{fiValueDateRangeArray[0]}:00").ToString("yyyy-MM-dd HH:mm:ss");
exp = Expression.AndAlso( exp = Expression.AndAlso(
Expression.GreaterThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueDateRangeArray[0]), exp.Type)), Expression.GreaterThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueDateRangeArray[0]), exp.Type)),
Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueDateRangeArray[1]), exp.Type))); Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueDateRangeArray[1]), exp.Type)));
break; break;
case DynamicFilterOperator.Any: case DynamicFilterOperator.Any:
case DynamicFilterOperator.NotAny: case DynamicFilterOperator.NotAny:
var fiValueAnyArray = fi.Value.Split(','); var fiValueAnyArray = getFiListValue();
if (fiValueAnyArray.Length == 0) break;
var fiValueAnyArrayType = exp.Type.MakeArrayType(); var fiValueAnyArrayType = exp.Type.MakeArrayType();
exp = Expression.Call(GetMethodEnumerableContains(exp.Type), Expression.Constant(Utils.GetDataReaderValue(fiValueAnyArrayType, fiValueAnyArray), fiValueAnyArrayType), exp); exp = Expression.Call(GetMethodEnumerableContains(exp.Type), Expression.Constant(Utils.GetDataReaderValue(fiValueAnyArrayType, fiValueAnyArray), fiValueAnyArrayType), exp);
if (fi.Operator == DynamicFilterOperator.NotAny) exp = Expression.Not(exp); if (fi.Operator == DynamicFilterOperator.NotAny) exp = Expression.Not(exp);
break; break;
} }
string[] getFiListValue()
{
if (fi.Value is string fiValueString) return fiValueString.Split(',');
if (fi.Value is IEnumerable fiValueIe)
{
var fiValueList = new List<string>();
foreach (var fiValueIeItem in fiValueIe)
fiValueList.Add(string.Concat(fiValueIeItem));
return fiValueList.ToArray();
}
return new string[0];
}
var sql = _commonExpression.ExpressionWhereLambda(_tables, exp, null, null, _params); var sql = _commonExpression.ExpressionWhereLambda(_tables, exp, null, null, _params);
sb.Append(sql); sb.Append(sql);

View File

@ -28,7 +28,7 @@ namespace FreeSql.Internal.Model
/// <summary> /// <summary>
/// 值 /// 值
/// </summary> /// </summary>
public string Value { get; set; } public object Value { get; set; }
/// <summary> /// <summary>
/// Filters 下的逻辑运算符 /// Filters 下的逻辑运算符
@ -93,13 +93,13 @@ namespace FreeSql.Internal.Model
/// <summary> /// <summary>
/// &gt;= and &lt;<para></para> /// &gt;= and &lt;<para></para>
/// 此时 Value 的值格式为逗号分割value1,value2 /// 此时 Value 的值格式为逗号分割value1,value2 或者数组
/// </summary> /// </summary>
Range, Range,
/// <summary> /// <summary>
/// &gt;= and &lt;<para></para> /// &gt;= and &lt;<para></para>
/// 此时 Value 的值格式为逗号分割date1,date2<para></para> /// 此时 Value 的值格式为逗号分割date1,date2 或者数组<para></para>
/// 这是专门为日期范围查询定制的操作符,它会处理 date2 + 1比如<para></para> /// 这是专门为日期范围查询定制的操作符,它会处理 date2 + 1比如<para></para>
/// 当 date2 选择的是 2020-05-30那查询的时候是 &lt; 2020-05-31<para></para> /// 当 date2 选择的是 2020-05-30那查询的时候是 &lt; 2020-05-31<para></para>
/// 当 date2 选择的是 2020-05那查询的时候是 &lt; 2020-06<para></para> /// 当 date2 选择的是 2020-05那查询的时候是 &lt; 2020-06<para></para>
@ -112,12 +112,12 @@ namespace FreeSql.Internal.Model
/// <summary> /// <summary>
/// in (1,2,3)<para></para> /// in (1,2,3)<para></para>
/// 此时 Value 的值格式为逗号分割value1,value2,value3... /// 此时 Value 的值格式为逗号分割value1,value2,value3... 或者数组
/// </summary> /// </summary>
Any, Any,
/// <summary> /// <summary>
/// not in (1,2,3)<para></para> /// not in (1,2,3)<para></para>
/// 此时 Value 的值格式为逗号分割value1,value2,value3... /// 此时 Value 的值格式为逗号分割value1,value2,value3... 或者数组
/// </summary> /// </summary>
NotAny NotAny
} }