- 增加 ISelect.WhereDynamicFilter 方法实现动态过滤条件(与前端交互);

This commit is contained in:
28810 2020-05-07 22:54:16 +08:00
parent ebe1b7a34f
commit e3dba006cf
6 changed files with 556 additions and 164 deletions

View File

@ -1,6 +1,7 @@
using FreeSql;
using FreeSql.DataAnnotations;
using FreeSql.Extensions;
using FreeSql.Internal.Model;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
@ -87,6 +88,43 @@ namespace base_entity
new Products { title = "product-4" }.Save();
new Products { title = "product-5" }.Save();
Products.Select.WhereDynamicFilter(JsonConvert.DeserializeObject<DynamicFilterInfo>(@"
{
""Logic"" : ""Or"",
""Filters"" :
[
{
""Field"" : ""title"",
""Operator"" : ""eq"",
""Value"" : ""product-1"",
""Filters"" :
[
{
""Field"" : ""title"",
""Operator"" : ""contains"",
""Value"" : ""product-1111"",
}
]
},
{
""Field"" : ""title"",
""Operator"" : ""eq"",
""Value"" : ""product-2""
},
{
""Field"" : ""title"",
""Operator"" : ""eq"",
""Value"" : ""product-3""
},
{
""Field"" : ""title"",
""Operator"" : ""eq"",
""Value"" : ""product-4""
},
]
}
")).ToList();
var items1 = Products.Select.Limit(10).OrderByDescending(a => a.CreateTime).ToList();
var items2 = fsql.Select<Products>().Limit(10).OrderByDescending(a => a.CreateTime).ToList();

View File

@ -1,4 +1,6 @@
using FreeSql.DataAnnotations;
using FreeSql.Internal.Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
@ -1931,5 +1933,105 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title""
[Navigate(nameof(ParentCode))]
public VM_District_Parent Parent { get; set; }
}
[Fact]
public void WhereDynamicFilter()
{
var fsql = g.sqlite;
var sql = fsql.Select<VM_District_Parent>().WhereDynamicFilter(JsonConvert.DeserializeObject<DynamicFilterInfo>(@"
{
""Logic"" : ""Or"",
""Filters"" :
[
{
""Field"" : ""Code"",
""Operator"" : ""Contains"",
""Value"" : ""val1"",
""Filters"" :
[
{
""Field"" : ""Name"",
""Operator"" : ""StartsWith"",
""Value"" : ""val2"",
}
]
},
{
""Field"" : ""Name"",
""Operator"" : ""EndsWith"",
""Value"" : ""val3""
},
{
""Field"" : ""ParentCode"",
""Operator"" : ""Equals"",
""Value"" : ""val4""
}
]
}
")).ToSql();
Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""ParentCode""
FROM ""D_District"" a
WHERE (((a.""Code"") LIKE '%val1%' AND (a.""Name"") LIKE 'val2%' OR (a.""Name"") LIKE '%val3' OR a.""ParentCode"" = 'val4'))", sql);
sql = fsql.Select<VM_District_Parent>().WhereDynamicFilter(JsonConvert.DeserializeObject<DynamicFilterInfo>(@"
{
""Logic"" : ""Or"",
""Filters"" :
[
{
""Field"" : ""Code"",
""Operator"" : ""NotContains"",
""Value"" : ""val1"",
""Filters"" :
[
{
""Field"" : ""Name"",
""Operator"" : ""NotStartsWith"",
""Value"" : ""val2"",
}
]
},
{
""Field"" : ""Name"",
""Operator"" : ""NotEndsWith"",
""Value"" : ""val3""
},
{
""Field"" : ""ParentCode"",
""Operator"" : ""NotEqual"",
""Value"" : ""val4""
},
{
""Field"" : ""Parent.Code"",
""Operator"" : ""eq"",
""Value"" : ""val11"",
""Filters"" :
[
{
""Field"" : ""Parent.Name"",
""Operator"" : ""contains"",
""Value"" : ""val22"",
}
]
},
{
""Field"" : ""Parent.Name"",
""Operator"" : ""eq"",
""Value"" : ""val33""
},
{
""Field"" : ""Parent.ParentCode"",
""Operator"" : ""eq"",
""Value"" : ""val44""
}
]
}
")).ToSql();
Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""ParentCode"", a__Parent.""Code"" as4, a__Parent.""Name"" as5, a__Parent.""ParentCode"" as6
FROM ""D_District"" a
LEFT JOIN ""D_District"" a__Parent ON a__Parent.""Code"" = a.""ParentCode""
WHERE ((not((a.""Code"") LIKE '%val1%') AND not((a.""Name"") LIKE 'val2%') OR not((a.""Name"") LIKE '%val3') OR a.""ParentCode"" <> 'val4' OR a__Parent.""Code"" = 'val11' AND (a__Parent.""Name"") LIKE '%val22%' OR a__Parent.""Name"" = 'val33' OR a__Parent.""ParentCode"" = 'val44'))", sql);
}
}
}

View File

@ -1276,6 +1276,13 @@
<param name="parms">参数</param>
<returns></returns>
</member>
<member name="M:FreeSql.ISelect0`2.WhereDynamicFilter(FreeSql.Internal.Model.DynamicFilterInfo)">
<summary>
动态过滤条件
</summary>
<param name="filter"></param>
<returns></returns>
</member>
<member name="M:FreeSql.ISelect0`2.DisableGlobalFilter(System.String[])">
<summary>
禁用全局过滤功能,不传参数时将禁用所有
@ -2310,6 +2317,137 @@
<param name="parms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteReaderAsync(System.Func{System.Data.Common.DbDataReader,System.Threading.Tasks.Task},System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
查询若使用读写分离查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
</summary>
<param name="readerHander"></param>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteReaderAsync(System.Func{System.Data.Common.DbDataReader,System.Threading.Tasks.Task},System.String,System.Object)">
<summary>
查询ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 })
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteArrayAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
查询
</summary>
<param name="cmdText"></param>
<param name="cmdParms"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteArrayAsync(System.String,System.Object)">
<summary>
查询ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 })
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataSetAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
查询
</summary>
<param name="cmdText"></param>
<param name="cmdParms"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataSetAsync(System.String,System.Object)">
<summary>
查询ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 })
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataTableAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
查询
</summary>
<param name="cmdText"></param>
<param name="cmdParms"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataTableAsync(System.String,System.Object)">
<summary>
查询ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 })
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteNonQueryAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
在【主库】执行
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteNonQueryAsync(System.String,System.Object)">
<summary>
在【主库】执行ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 })
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteScalarAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
在【主库】执行
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteScalarAsync(System.String,System.Object)">
<summary>
在【主库】执行ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 })
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``1(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
执行SQL返回对象集合QueryAsync&lt;User&gt;("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 })
</summary>
<typeparam name="T"></typeparam>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``1(System.String,System.Object)">
<summary>
执行SQL返回对象集合QueryAsync&lt;User&gt;("select * from user where age > ?age", new { age = 25 })
</summary>
<typeparam name="T"></typeparam>
<param name="cmdText"></param>
<param name="parms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``2(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
执行SQL返回对象集合Query&lt;User&gt;("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 })
</summary>
<typeparam name="T1"></typeparam>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``2(System.String,System.Object)">
<summary>
执行SQL返回对象集合Query&lt;User&gt;("select * from user where age > ?age; select * from address", new { age = 25 })
</summary>
<typeparam name="T1"></typeparam>
<param name="cmdText"></param>
<param name="parms"></param>
<returns></returns>
</member>
<member name="E:FreeSql.IAop.ParseExpression">
<summary>
可自定义解析表达式
@ -2793,6 +2931,74 @@
<param name="where">表达式</param>
<returns></returns>
</member>
<member name="T:FreeSql.Internal.Model.DynamicFilterInfo">
<summary>
动态过滤条件
</summary>
</member>
<member name="P:FreeSql.Internal.Model.DynamicFilterInfo.Field">
<summary>
属性名Name<para></para>
导航属性Parent.Name<para></para>
多表b.Name<para></para>
</summary>
</member>
<member name="P:FreeSql.Internal.Model.DynamicFilterInfo.Operator">
<summary>
操作符
</summary>
</member>
<member name="P:FreeSql.Internal.Model.DynamicFilterInfo.Value">
<summary>
</summary>
</member>
<member name="P:FreeSql.Internal.Model.DynamicFilterInfo.Logic">
<summary>
Filters 下的逻辑运算符
</summary>
</member>
<member name="P:FreeSql.Internal.Model.DynamicFilterInfo.Filters">
<summary>
子过滤条件,它与当前的逻辑关系是 And<para></para>
注意:当前 Field 可以留空
</summary>
</member>
<member name="F:FreeSql.Internal.Model.DynamicFilterOperator.Contains">
<summary>
like
</summary>
</member>
<member name="F:FreeSql.Internal.Model.DynamicFilterOperator.Equals">
<summary>
=
</summary>
</member>
<member name="F:FreeSql.Internal.Model.DynamicFilterOperator.NotEqual">
<summary>
&lt;&gt;
</summary>
</member>
<member name="F:FreeSql.Internal.Model.DynamicFilterOperator.GreaterThan">
<summary>
&gt;
</summary>
</member>
<member name="F:FreeSql.Internal.Model.DynamicFilterOperator.GreaterThanOrEqual">
<summary>
&gt;=
</summary>
</member>
<member name="F:FreeSql.Internal.Model.DynamicFilterOperator.LessThan">
<summary>
&lt;
</summary>
</member>
<member name="F:FreeSql.Internal.Model.DynamicFilterOperator.LessThanOrEqual">
<summary>
&lt;=
</summary>
</member>
<member name="P:FreeSql.Internal.Model.TableRef.RefMiddleEntityType">
<summary>
中间表,多对多
@ -2837,6 +3043,12 @@
<param name="timeout">超时</param>
<returns></returns>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IObjectPool`1.GetAsync">
<summary>
获取资源
</summary>
<returns></returns>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IObjectPool`1.Return(FreeSql.Internal.ObjectPool.Object{`0},System.Boolean)">
<summary>
使用完毕后,归还资源
@ -2907,6 +3119,12 @@
</summary>
<param name="obj">资源对象</param>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IPolicy`1.OnGetAsync(FreeSql.Internal.ObjectPool.Object{`0})">
<summary>
从对象池获取对象成功的时候触发,通过该方法统计或初始化对象
</summary>
<param name="obj">资源对象</param>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IPolicy`1.OnReturn(FreeSql.Internal.ObjectPool.Object{`0})">
<summary>
归还对象给对象池的时候触发
@ -3539,167 +3757,4 @@
</summary>
</member>
</members>
</doc>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Or``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})">
<summary>
使用 or 拼接两个 lambda 表达式
</summary>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Or``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})">
<summary>
使用 or 拼接两个 lambda 表达式
</summary>
<param name="exp1"></param>
<param name="condition">true 时生效</param>
<param name="exp2"></param>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Not``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Boolean)">
<summary>
将 lambda 表达式取反
</summary>
<param name="exp"></param>
<param name="condition">true 时生效</param>
<returns></returns>
</member>
<member name="M:FreeUtil.NewMongodbId">
<summary>
生成类似Mongodb的ObjectId有序、不重复Guid
</summary>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1">
<summary>
插入数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(``0)">
<summary>
插入数据,传入实体
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(``0[])">
<summary>
插入数据,传入实体数组
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(System.Collections.Generic.List{``0})">
<summary>
插入数据,传入实体集合
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(System.Collections.Generic.IEnumerable{``0})">
<summary>
插入数据,传入实体集合
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.Update``1">
<summary>
修改数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Update``1(System.Object)">
<summary>
修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}
</summary>
<typeparam name="T1"></typeparam>
<param name="dywhere">主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合</param>
<returns></returns>
</member>
<member name="M:IFreeSql.Select``1">
<summary>
查询数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Select``1(System.Object)">
<summary>
查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}
</summary>
<typeparam name="T1"></typeparam>
<param name="dywhere">主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合</param>
<returns></returns>
</member>
<member name="M:IFreeSql.Delete``1">
<summary>
删除数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Delete``1(System.Object)">
<summary>
删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}
</summary>
<typeparam name="T1"></typeparam>
<param name="dywhere">主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合</param>
<returns></returns>
</member>
<member name="M:IFreeSql.Transaction(System.Action)">
<summary>
开启事务不支持异步60秒未执行完成可能被其他线程事务自动提交
</summary>
<param name="handler">事务体 () => {}</param>
</member>
<member name="M:IFreeSql.Transaction(System.TimeSpan,System.Action)">
<summary>
开启事务(不支持异步)
</summary>
<param name="timeout">超时,未执行完成(可能)被其他线程事务自动提交</param>
<param name="handler">事务体 () => {}</param>
</member>
<member name="M:IFreeSql.Transaction(System.Data.IsolationLevel,System.TimeSpan,System.Action)">
<summary>
开启事务(不支持异步)
</summary>
<param name="isolationLevel"></param>
<param name="handler">事务体 () => {}</param>
<param name="timeout">超时,未执行完成(可能)被其他线程事务自动提交</param>
</member>
<member name="P:IFreeSql.Ado">
<summary>
数据库访问对象
</summary>
</member>
<member name="P:IFreeSql.Aop">
<summary>
所有拦截方法都在这里
</summary>
</member>
<member name="P:IFreeSql.CodeFirst">
<summary>
CodeFirst 模式开发相关方法
</summary>
</member>
<member name="P:IFreeSql.DbFirst">
<summary>
DbFirst 模式开发相关方法
</summary>
</member>
<member name="P:IFreeSql.GlobalFilter">
<summary>
全局过滤设置,可默认附加为 Select/Update/Delete 条件
</summary>
</member>
</members>
</doc>

View File

@ -1,4 +1,5 @@
using System;
using FreeSql.Internal.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
@ -261,6 +262,13 @@ namespace FreeSql
/// <returns></returns>
TSelect WhereIf(bool condition, string sql, object parms = null);
/// <summary>
/// 动态过滤条件
/// </summary>
/// <param name="filter"></param>
/// <returns></returns>
TSelect WhereDynamicFilter(DynamicFilterInfo filter);
/// <summary>
/// 禁用全局过滤功能,不传参数时将禁用所有
/// </summary>

View File

@ -1025,6 +1025,111 @@ namespace FreeSql.Internal.CommonProvider
if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms));
return this as TSelect;
}
static MethodInfo MethodStringContains = typeof(string).GetMethod("Contains", new[] { typeof(string) });
static MethodInfo MethodStringStartsWith = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
static MethodInfo MethodStringEndsWith = typeof(string).GetMethod("EndsWith", new[] { typeof(string) });
public TSelect WhereDynamicFilter(DynamicFilterInfo filter)
{
if (filter == null) return this as TSelect;
var sb = new StringBuilder();
ParseFilter(DynamicFilterLogic.And, filter, true);
this.Where(sb.ToString());
sb.Clear();
return this as TSelect;
void ParseFilter(DynamicFilterLogic logic, DynamicFilterInfo fi, bool isend)
{
if (string.IsNullOrEmpty(fi.Field) == false)
{
var field = fi.Field.Split('.').Select(a => a.Trim()).ToArray();
Expression exp = null;
if (field.Length == 1)
{
foreach (var tb in _tables)
{
if (tb.Table.ColumnsByCs.TryGetValue(field[0], out var col) &&
tb.Table.Properties.TryGetValue(field[0], out var prop))
{
tb.Parameter = Expression.Parameter(tb.Table.Type, tb.Alias);
exp = Expression.MakeMemberAccess(tb.Parameter, prop);
break;
}
}
if (exp == null) throw new Exception($"无法匹配 {fi.Field}");
}
else
{
var firstTb = _tables[0];
var firstTbs = _tables.Where(a => a.AliasInit == field[0]).ToArray();
if (firstTbs.Length == 1)
{
firstTb = firstTbs[0];
}
firstTb.Parameter = Expression.Parameter(firstTb.Table.Type, firstTb.Alias);
var currentType = firstTb.Table.Type;
Expression currentExp = firstTb.Parameter;
for (var x = 0; x < field.Length; x++)
{
var tmp1 = field[x];
if (_commonUtils.GetTableByEntity(currentType).Properties.TryGetValue(tmp1, out var prop) == false)
throw new ArgumentException($"{currentType.DisplayCsharp()} 无法找到属性名 {tmp1}");
currentType = prop.PropertyType;
currentExp = Expression.MakeMemberAccess(currentExp, prop);
}
exp = currentExp;
}
switch (fi.Operator)
{
case DynamicFilterOperator.Contains: exp = Expression.Call(exp, MethodStringContains, Expression.Constant(fi.Value)); break;
case DynamicFilterOperator.StartsWith: exp = Expression.Call(exp, MethodStringStartsWith, Expression.Constant(fi.Value)); break;
case DynamicFilterOperator.EndsWith: exp = Expression.Call(exp, MethodStringEndsWith, Expression.Constant(fi.Value)); break;
case DynamicFilterOperator.NotContains: exp = Expression.Not(Expression.Call(exp, MethodStringContains, Expression.Constant(fi.Value))); break;
case DynamicFilterOperator.NotStartsWith: exp = Expression.Not(Expression.Call(exp, MethodStringStartsWith, Expression.Constant(fi.Value))); break;
case DynamicFilterOperator.NotEndsWith: exp = Expression.Not(Expression.Call(exp, MethodStringEndsWith, Expression.Constant(fi.Value))); break;
case DynamicFilterOperator.Equals:
case DynamicFilterOperator.Eq: exp = Expression.Equal(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break;
case DynamicFilterOperator.NotEqual: exp = Expression.NotEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break;
case DynamicFilterOperator.GreaterThan: exp = Expression.GreaterThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break;
case DynamicFilterOperator.GreaterThanOrEqual: exp = Expression.GreaterThanOrEqual(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;
}
var sql = _commonExpression.ExpressionWhereLambda(_tables, exp, null, null, _params);
sb.Append(sql);
}
if (fi.Filters?.Any() == true)
{
if (string.IsNullOrEmpty(fi.Field) == false)
sb.Append(" AND ");
if (fi.Logic == DynamicFilterLogic.Or) sb.Append("(");
for (var x = 0; x < fi.Filters.Count; x++)
ParseFilter(fi.Logic, fi.Filters[x], x == fi.Filters.Count - 1);
if (fi.Logic == DynamicFilterLogic.Or) sb.Append(")");
}
if (isend == false)
{
if (string.IsNullOrEmpty(fi.Field) == false || fi.Filters?.Any() == true)
{
switch (filter.Logic)
{
case DynamicFilterLogic.And: sb.Append(" AND "); break;
case DynamicFilterLogic.Or: sb.Append(" OR "); break;
}
}
}
}
}
public TSelect DisableGlobalFilter(params string[] name)
{
if (_whereGlobalFilter.Any() == false) return this as TSelect;

View File

@ -0,0 +1,84 @@
using FreeSql;
using FreeSql.Internal;
using FreeSql.Internal.CommonProvider;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
namespace FreeSql.Internal.Model
{
/// <summary>
/// 动态过滤条件
/// </summary>
public class DynamicFilterInfo
{
/// <summary>
/// 属性名Name<para></para>
/// 导航属性Parent.Name<para></para>
/// 多表b.Name<para></para>
/// </summary>
public string Field { get; set; }
/// <summary>
/// 操作符
/// </summary>
public DynamicFilterOperator Operator { get; set; }
/// <summary>
/// 值
/// </summary>
public string Value { get; set; }
/// <summary>
/// Filters 下的逻辑运算符
/// </summary>
public DynamicFilterLogic Logic { get; set; }
/// <summary>
/// 子过滤条件,它与当前的逻辑关系是 And<para></para>
/// 注意:当前 Field 可以留空
/// </summary>
public List<DynamicFilterInfo> Filters { get; set; }
}
public enum DynamicFilterLogic { And, Or }
public enum DynamicFilterOperator
{
/// <summary>
/// like
/// </summary>
Contains,
StartsWith,
EndsWith,
NotContains,
NotStartsWith,
NotEndsWith,
/// <summary>
/// =
/// </summary>
Equals,
Eq,
/// <summary>
/// &lt;&gt;
/// </summary>
NotEqual,
/// <summary>
/// &gt;
/// </summary>
GreaterThan,
/// <summary>
/// &gt;=
/// </summary>
GreaterThanOrEqual,
/// <summary>
/// &lt;
/// </summary>
LessThan,
/// <summary>
/// &lt;=
/// </summary>
LessThanOrEqual,
}
}