- 增加 ISelect OrderByPropertyName 方法 #446 #278 #380 #361 #197;

This commit is contained in:
28810 2020-09-18 12:33:07 +08:00
parent 8f9efe1f11
commit 46bc2189c4
5 changed files with 161 additions and 38 deletions

View File

@ -532,5 +532,14 @@
<param name="that"></param>
<returns></returns>
</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>
</doc>

View File

@ -2304,6 +2304,67 @@ WHERE ((a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-1
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);
sql = fsql.Select<VM_District_Parent>().OrderByPropertyName("Parent.Name").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.""CreateTime"", a.""testint"", a.""ParentCode"", a__Parent.""Code"" as6, a__Parent.""Name"" as7, a__Parent.""CreateTime"" as8, a__Parent.""testint"" as9, a__Parent.""ParentCode"" as10
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'))
ORDER BY a__Parent.""Name""", sql);
}
}
}

View File

@ -1943,6 +1943,25 @@
<param name="parms">参数</param>
<returns></returns>
</member>
<member name="M:FreeSql.ISelect0`2.OrderByPropertyName(System.String,System.Boolean)">
<summary>
按属性名字符串排序(支持导航属性)<para></para>
属性名Name<para></para>导航属性Parent.Name<para></para>多表b.Name
</summary>
<param name="property">属性名Name<para></para>导航属性Parent.Name<para></para>多表b.Name</param>
<param name="isAscending">顺序 | 倒序</param>
<returns></returns>
</member>
<member name="M:FreeSql.ISelect0`2.OrderByPropertyNameIf(System.Boolean,System.String,System.Boolean)">
<summary>
按属性名字符串排序(支持导航属性)<para></para>
属性名Name<para></para>导航属性Parent.Name<para></para>多表b.Name
</summary>
<param name="condition">true 时生效</param>
<param name="property">属性名Name<para></para>导航属性Parent.Name<para></para>多表b.Name</param>
<param name="isAscending">顺序 | 倒序</param>
<returns></returns>
</member>
<member name="M:FreeSql.ISelect0`2.Skip(System.Int32)">
<summary>
查询向后偏移行数

View File

@ -337,6 +337,23 @@ namespace FreeSql
/// <param name="parms">参数</param>
/// <returns></returns>
TSelect OrderBy(bool condition, string sql, object parms = null);
/// <summary>
/// 按属性名字符串排序(支持导航属性)<para></para>
/// 属性名Name<para></para>导航属性Parent.Name<para></para>多表b.Name
/// </summary>
/// <param name="property">属性名Name<para></para>导航属性Parent.Name<para></para>多表b.Name</param>
/// <param name="isAscending">顺序 | 倒序</param>
/// <returns></returns>
TSelect OrderByPropertyName(string property, bool isAscending = true);
/// <summary>
/// 按属性名字符串排序(支持导航属性)<para></para>
/// 属性名Name<para></para>导航属性Parent.Name<para></para>多表b.Name
/// </summary>
/// <param name="condition">true 时生效</param>
/// <param name="property">属性名Name<para></para>导航属性Parent.Name<para></para>多表b.Name</param>
/// <param name="isAscending">顺序 | 倒序</param>
/// <returns></returns>
TSelect OrderByPropertyNameIf(bool condition, string property, bool isAscending = true);
/// <summary>
/// 查询向后偏移行数

View File

@ -442,25 +442,10 @@ namespace FreeSql.Internal.CommonProvider
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) });
static ConcurrentDictionary<Type, MethodInfo> MethodEnumerableContainsDic = new ConcurrentDictionary<Type, MethodInfo>();
static MethodInfo GetMethodEnumerableContains(Type elementType) => MethodEnumerableContainsDic.GetOrAdd(elementType, et => typeof(Enumerable).GetMethods().Where(a => a.Name == "Contains").FirstOrDefault().MakeGenericMethod(elementType));
public TSelect WhereDynamicFilter(DynamicFilterInfo filter)
public Expression ConvertStringPropertyToExpression(string property)
{
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();
if (string.IsNullOrEmpty(property)) return null;
var field = property.Split('.').Select(a => a.Trim()).ToArray();
Expression exp = null;
if (field.Length == 1)
@ -475,7 +460,7 @@ namespace FreeSql.Internal.CommonProvider
break;
}
}
if (exp == null) throw new Exception($"无法匹配 {fi.Field}");
if (exp == null) throw new Exception($"无法匹配 {property}");
}
else
{
@ -497,7 +482,39 @@ namespace FreeSql.Internal.CommonProvider
}
exp = currentExp;
}
return exp;
}
public TSelect OrderByPropertyName(string property, bool isAscending = true) => OrderByPropertyNameIf(true, property, isAscending);
public TSelect OrderByPropertyNameIf(bool condition, string property, bool isAscending = true)
{
if (condition == false) return this as TSelect;
Expression exp = ConvertStringPropertyToExpression(property);
if (exp == null) return this as TSelect;
var field = _commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null);
if (isAscending) return this.OrderBy(field);
return this.OrderBy($"{field} DESC");
}
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) });
static ConcurrentDictionary<Type, MethodInfo> MethodEnumerableContainsDic = new ConcurrentDictionary<Type, MethodInfo>();
static MethodInfo GetMethodEnumerableContains(Type elementType) => MethodEnumerableContainsDic.GetOrAdd(elementType, et => typeof(Enumerable).GetMethods().Where(a => a.Name == "Contains").FirstOrDefault().MakeGenericMethod(elementType));
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)
{
Expression exp = ConvertStringPropertyToExpression(fi.Field);
switch (fi.Operator)
{
case DynamicFilterOperator.Contains: exp = Expression.Call(exp, MethodStringContains, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break;