v11.16 优化高级搜索的代码生成,支持生成魔方控制台的高级查询代码

This commit is contained in:
大石头 2024-12-29 16:56:35 +08:00
parent 2de8ddf627
commit 4adf6ef2e1
13 changed files with 241 additions and 76 deletions

View File

@ -1,5 +1,4 @@
using System.Reflection;
using System.Text;
using System.Text;
using NewLife;
using NewLife.Collections;
using NewLife.Log;
@ -1655,11 +1654,11 @@ public class EntityBuilder : ClassBuilder
var methodName = columns.Select(e => e.Name).Join("And");
methodName = $"FindBy{methodName}";
var (ps, ps2) = GetParameters(columns);
var ps = GetParameters(columns);
var args = ps.Join(", ", e => $"{e.Value} {e.Key}");
// 如果方法名已存在,则不生成
var key = $"{methodName}({ps2.Join(",", e => e.Value)})";
var key = $"{methodName}({ps.Join(",", e => e.Value)})";
if (Members.Contains(key)) return false;
Members.Add(key);
@ -1758,11 +1757,11 @@ public class EntityBuilder : ClassBuilder
var methodName = columns.Select(e => e.Name).Join("And");
methodName = $"FindAllBy{methodName}";
var (ps, ps2) = GetParameters(columns);
var ps = GetParameters(columns);
var args = ps.Join(", ", e => $"{e.Value} {e.Key}");
// 如果方法名已存在,则不生成
var key = $"{methodName}({ps2.Join(",", e => e.Value)})";
var key = $"{methodName}({ps.Join(",", e => e.Value)})";
if (Members.Contains(key)) return false;
Members.Add(key);
@ -1824,7 +1823,7 @@ public class EntityBuilder : ClassBuilder
return true;
}
private (IDictionary<String, String>, IDictionary<String, String>) GetParameters(IList<IDataColumn> columns)
private IDictionary<String, String> GetParameters(IList<IDataColumn> columns)
{
var ps = new Dictionary<String, String>();
var ps2 = new Dictionary<String, String>();
@ -1850,7 +1849,8 @@ public class EntityBuilder : ClassBuilder
ps2[dc.CamelName()] = type;
}
return (ps, ps2);
//return (ps, ps2);
return ps2;
}
/// <summary>自定义查询区域</summary>
@ -1931,47 +1931,16 @@ public class EntityBuilder : ClassBuilder
protected virtual IList<IDataColumn> BuildAdvanceSearch()
{
// 收集索引信息,索引中的所有字段都参与,构造一个高级查询模板
var idx = Table.Indexes ?? [];
var cs = new List<IDataColumn>();
if (idx != null && idx.Count > 0)
{
// 索引中的所有字段,按照表字段顺序
var dcs = idx.SelectMany(e => e.Columns).Distinct().ToArray();
foreach (var dc in Table.Columns)
{
// 主键和自增,不参与
if (dc.PrimaryKey || dc.Identity) continue;
if (dc.Name.EqualIgnoreCase(dcs) || dc.ColumnName.EqualIgnoreCase(dcs)) cs.Add(dc);
}
}
if (cs.Count <= 0) return cs;
var builder = new SearchBuilder(Table) { Nullable = Option.Nullable };
var cs = builder.GetColumns();
if (cs.Count == 0) return [];
var returnName = ClassName;
// 时间字段。无差别支持UpdateTime/CreateTime
var dcTime = cs.FirstOrDefault(e => e.DataScale.StartsWithIgnoreCase("time"));
dcTime ??= cs.FirstOrDefault(e => e.DataType == typeof(DateTime));
dcTime ??= Table.GetColumns(["UpdateTime", "CreateTime"])?.FirstOrDefault();
var dcSnow = cs.FirstOrDefault(e => e.PrimaryKey && !e.Identity && e.DataType == typeof(Int64));
if (dcTime != null) cs.Remove(dcTime);
cs.RemoveAll(e => e.Name.EqualIgnoreCase("key", "page"));
if (dcSnow != null || dcTime != null)
cs.RemoveAll(e => e.Name.EqualIgnoreCase("start", "end"));
var (ps, ps2) = GetParameters(cs);
var ps = builder.GetParameters(cs, true, true, true);
// 如果方法名已存在,则不生成
if (dcTime != null)
{
ps2["start"] = "DateTime";
ps2["end"] = "DateTime";
}
ps2["key"] = "String";
ps2["page"] = "PageParameter";
var key = $"Search({ps2.Join(",", e => e.Value)})";
var key = $"Search({ps.Join(",", e => e.Value)})";
if (Members.Contains(key)) return cs;
Members.Add(key);
@ -1981,27 +1950,20 @@ public class EntityBuilder : ClassBuilder
{
WriteLine("/// <param name=\"{0}\">{1}</param>", dc.CamelName(), dc.Description);
}
var dcTime = builder.DataTime;
if (dcTime != null)
{
WriteLine("/// <param name=\"start\">{0}开始</param>", dcTime.DisplayName);
WriteLine("/// <param name=\"end\">{0}结束</param>", dcTime.DisplayName);
}
else if (dcSnow != null)
{
WriteLine("/// <param name=\"start\">{0}开始</param>", dcSnow.DisplayName);
WriteLine("/// <param name=\"end\">{0}结束</param>", dcSnow.DisplayName);
}
WriteLine("/// <param name=\"key\">关键字</param>");
WriteLine("/// <param name=\"page\">分页参数信息。可携带统计和数据权限扩展查询等信息</param>");
WriteLine("/// <returns>实体列表</returns>");
// 参数部分
var pis = ps.Join(", ", e => $"{e.Value} {e.Key}");
var piTime = dcTime == null ? "" : "DateTime start, DateTime end, ";
if (pis.Length > 0)
WriteLine("public static IList<{0}> Search({1}, {2}String key, PageParameter page)", returnName, pis, piTime);
else
WriteLine("public static IList<{0}> Search({2}String key, PageParameter page)", returnName, pis, piTime);
WriteLine("public static IList<{0}> Search({1})", returnName, pis);
WriteLine("{");
{
WriteLine("var exp = new WhereExpression();");
@ -2020,10 +1982,13 @@ public class EntityBuilder : ClassBuilder
WriteLine("if (!{0}.IsNullOrEmpty()) exp &= _.{1} == {0};", dc.CamelName(), dc.Name);
}
if (dcSnow != null)
WriteLine("exp &= _.{0}.Between(start, end, Meta.Factory.Snow);", dcSnow.Name);
else if (dcTime != null)
WriteLine("exp &= _.{0}.Between(start, end);", dcTime.Name);
if (dcTime != null)
{
if (dcTime.DataType == typeof(Int64))
WriteLine("exp &= _.{0}.Between(start, end, Meta.Factory.Snow);", dcTime.Name);
else
WriteLine("exp &= _.{0}.Between(start, end);", dcTime.Name);
}
WriteLine("if (!key.IsNullOrEmpty()) exp &= SearchWhereByKeys(key);");

123
XCode/Code/SearchBuilder.cs Normal file
View File

@ -0,0 +1,123 @@
using NewLife;
using NewLife.Reflection;
using XCode.DataAccessLayer;
namespace XCode.Code;
/// <summary>搜索功能代码生成器</summary>
public class SearchBuilder(IDataTable table)
{
#region
/// <summary>数据表</summary>
public IDataTable Table { get; set; } = table;
/// <summary>可为null上下文。生成String?等</summary>
public Boolean Nullable { get; set; }
/// <summary>数据时间字段</summary>
public IDataColumn? DataTime { get; set; }
#endregion
#region
#endregion
#region
/// <summary>获取可用于搜索的字段列表</summary>
/// <returns></returns>
public IList<IDataColumn> GetColumns()
{
// 收集索引信息,索引中的所有字段都参与,构造一个高级查询模板
var idx = Table.Indexes ?? [];
var cs = new List<IDataColumn>();
if (idx != null && idx.Count > 0)
{
// 索引中的所有字段,按照表字段顺序
var dcs = idx.SelectMany(e => e.Columns).Distinct().ToArray();
foreach (var dc in Table.Columns)
{
// 主键和自增,不参与
if (dc.PrimaryKey || dc.Identity) continue;
if (dc.Name.EqualIgnoreCase(dcs) || dc.ColumnName.EqualIgnoreCase(dcs)) cs.Add(dc);
}
}
// 特殊字段
foreach (var dc in Table.Columns)
{
if (cs.Contains(dc)) continue;
if (dc.DataType.IsInt() && dc.DataType.IsEnum)
cs.Add(dc);
else if (dc.DataType.IsInt() && !dc.Map.IsNullOrEmpty())
cs.Add(dc);
}
foreach (var dc in Table.Columns)
{
if (cs.Contains(dc)) continue;
if (dc.Name.EqualIgnoreCase("enable", "isDeleted") && dc.DataType == typeof(Boolean))
cs.Add(dc);
}
if (cs.Count == 0) return [];
// 时间字段。无差别支持UpdateTime/CreateTime
var dcTime = cs.FirstOrDefault(e => e.DataScale.StartsWithIgnoreCase("time"));
dcTime ??= cs.FirstOrDefault(e => e.DataType == typeof(DateTime));
dcTime ??= Table.GetColumns(["UpdateTime", "CreateTime"])?.FirstOrDefault();
var dcSnow = cs.FirstOrDefault(e => e.PrimaryKey && !e.Identity && e.DataType == typeof(Int64));
if (dcTime != null) cs.Remove(dcTime);
cs.RemoveAll(e => e.Name.EqualIgnoreCase("key", "page"));
if (dcSnow != null || dcTime != null)
cs.RemoveAll(e => e.Name.EqualIgnoreCase("start", "end"));
DataTime = dcSnow ?? dcTime;
return cs;
}
/// <summary>获取参数列表。名称+类型</summary>
/// <param name="columns"></param>
/// <param name="includeTime"></param>
/// <param name="includeKey"></param>
/// <param name="includePage"></param>
/// <returns></returns>
public IDictionary<String, String> GetParameters(IList<IDataColumn> columns, Boolean includeTime = false, Boolean includeKey = false, Boolean includePage = false)
{
var ps = new Dictionary<String, String>();
foreach (var dc in columns)
{
var type = dc.Properties["Type"];
if (type.IsNullOrEmpty()) type = dc.DataType?.Name + "";
if (dc.DataType == typeof(Boolean))
type += "?";
else if (dc.DataType == typeof(String))
{
if (Nullable && dc.Nullable)
{
type += "?";
}
}
var p = type.LastIndexOf('.');
if (p > 0) type = type[(p + 1)..];
ps[dc.CamelName()] = type;
}
if (includeTime && DataTime != null)
{
ps["start"] = "DateTime";
ps["end"] = "DateTime";
}
if (includeKey)
ps["key"] = "String";
if (includePage)
ps["page"] = "PageParameter";
return ps;
}
#endregion
}

View File

@ -7,7 +7,7 @@
<Description>数据中间件支持MySQL、SQLite、SqlServer、Oracle、Postgresql、TDengine、达梦重点在缓存、性能、分表、自动建表。</Description>
<Company>新生命开发团队</Company>
<Copyright>©2002-2024 NewLife</Copyright>
<VersionPrefix>11.16</VersionPrefix>
<VersionPrefix>11.17</VersionPrefix>
<VersionSuffix>$([System.DateTime]::Now.ToString(`yyyy.MMdd`))</VersionSuffix>
<Version>$(VersionPrefix).$(VersionSuffix)</Version>
<FileVersion>$(Version)</FileVersion>

View File

@ -4,7 +4,9 @@ using System.IO;
using System.Linq;
using System.Text;
using NewLife;
using NewLife.Collections;
using NewLife.Log;
using NewLife.Reflection;
using XCode.Code;
using XCode.DataAccessLayer;
@ -310,6 +312,15 @@ public class CubeBuilder : ClassBuilder
if (Table.Columns.Any(c => c.Name.EqualIgnoreCase("TraceId")))
code = code.Replace("//ListFields.TraceUrl(", "ListFields.TraceUrl(");
var ss = BuildSearch();
if (!ss.IsNullOrEmpty())
{
var p1 = code.IndexOf(" //var deviceId = p[\"deviceId\"].ToInt(-1);");
var p2 = code.IndexOf("p);", p1);
code = code.Substring(0, p1) + ss + code.Substring(p2 + "p);".Length);
}
Writer.Write(code);
}
@ -321,15 +332,55 @@ public class CubeBuilder : ClassBuilder
#endregion
#region
///// <summary>写入</summary>
///// <param name="value"></param>
//protected override void WriteLine(String value = null)
//{
// if (!value.IsNullOrEmpty() && value.Length > 2 && value[0] == '<' && value[1] == '/') SetIndent(false);
private String BuildSearch()
{
// 收集索引信息,索引中的所有字段都参与,构造一个高级查询模板
var builder = new SearchBuilder(Table) { Nullable = Option.Nullable };
var cs = builder.GetColumns();
if (cs.Count <= 0) return null;
// base.WriteLine(value);
var ps = builder.GetParameters(cs, true, true, true);
// if (!value.IsNullOrEmpty() && value.Length > 2 && value[0] == '<' && value[1] != '/' && !value.Contains("</")) SetIndent(true);
//}
var sb = Pool.StringBuilder.Get();
var pis = new List<String>();
foreach (var dc in cs)
{
var name = dc.CamelName();
if (dc.DataType.IsInt())
{
if (dc.DataType.IsEnum)
sb.AppendLine($" var {name} = ({dc.DataType.Name})p[\"{name}\"].ToInt();");
else if (dc.DataType == typeof(Int64))
sb.AppendLine($" var {name} = p[\"{name}\"].ToLong(-1);");
else
sb.AppendLine($" var {name} = p[\"{name}\"].ToInt(-1);");
}
else if (dc.DataType == typeof(Boolean))
sb.AppendLine($" var {name} = p[\"{name}\"]?.ToBoolean();");
else if (dc.DataType == typeof(DateTime))
sb.AppendLine($" var {name} = p[\"{name}\"].ToDateTime();");
else if (dc.DataType == typeof(String))
sb.AppendLine($" var {name} = p[\"{name}\"];");
else
// 不支持的类型,跳过
continue;
pis.Add(name);
}
if (builder.DataTime != null)
{
sb.AppendLine();
sb.AppendLine(" var start = p[\"dtStart\"].ToDateTime();");
sb.AppendLine(" var end = p[\"dtEnd\"].ToDateTime();");
}
sb.AppendLine();
sb.AppendLine($" return {Table.Name}.Search({pis.Join(", ")}, p[\"Q\"], p);");
return sb.Return(true).TrimEnd();
}
#endregion
}

View File

@ -8,7 +8,7 @@
<Description>数据中间件,代码生成</Description>
<Company>新生命开发团队</Company>
<Copyright>©2002-2024 NewLife</Copyright>
<VersionPrefix>11.16</VersionPrefix>
<VersionPrefix>11.17</VersionPrefix>
<VersionSuffix>$([System.DateTime]::Now.ToString(`yyyy.MMdd`))</VersionSuffix>
<Version>$(VersionPrefix).$(VersionSuffix)</Version>
<FileVersion>$(Version)</FileVersion>

View File

@ -120,12 +120,13 @@ public partial class Area : Entity<Area>
/// <param name="pinYin">拼音</param>
/// <param name="jianPin">简拼</param>
/// <param name="geoHash">地址编码。字符串前缀相同越多地理距离越近8位精度19米6位610米</param>
/// <param name="enable">启用</param>
/// <param name="start">更新时间开始</param>
/// <param name="end">更新时间结束</param>
/// <param name="key">关键字</param>
/// <param name="page">分页参数信息。可携带统计和数据权限扩展查询等信息</param>
/// <returns>实体列表</returns>
public static IList<Area> Search(String? name, Int32 parentId, String? pinYin, String? jianPin, String? geoHash, DateTime start, DateTime end, String key, PageParameter page)
public static IList<Area> Search(String? name, Int32 parentId, String? pinYin, String? jianPin, String? geoHash, Boolean? enable, DateTime start, DateTime end, String key, PageParameter page)
{
var exp = new WhereExpression();
@ -134,6 +135,7 @@ public partial class Area : Entity<Area>
if (!pinYin.IsNullOrEmpty()) exp &= _.PinYin == pinYin;
if (!jianPin.IsNullOrEmpty()) exp &= _.JianPin == jianPin;
if (!geoHash.IsNullOrEmpty()) exp &= _.GeoHash == geoHash;
if (enable != null) exp &= _.Enable == enable;
exp &= _.UpdateTime.Between(start, end);
if (!key.IsNullOrEmpty()) exp &= SearchWhereByKeys(key);

View File

@ -130,18 +130,20 @@ public partial class Parameter : Entity<Parameter>
/// <param name="userId">用户。按用户区分参数用户0表示系统级</param>
/// <param name="category">类别</param>
/// <param name="name">名称</param>
/// <param name="enable">启用</param>
/// <param name="start">更新时间开始</param>
/// <param name="end">更新时间结束</param>
/// <param name="key">关键字</param>
/// <param name="page">分页参数信息。可携带统计和数据权限扩展查询等信息</param>
/// <returns>实体列表</returns>
public static IList<Parameter> Search(Int32 userId, String? category, String? name, DateTime start, DateTime end, String key, PageParameter page)
public static IList<Parameter> Search(Int32 userId, String? category, String? name, Boolean? enable, DateTime start, DateTime end, String key, PageParameter page)
{
var exp = new WhereExpression();
if (userId >= 0) exp &= _.UserID == userId;
if (!category.IsNullOrEmpty()) exp &= _.Category == category;
if (!name.IsNullOrEmpty()) exp &= _.Name == name;
if (enable != null) exp &= _.Enable == enable;
exp &= _.UpdateTime.Between(start, end);
if (!key.IsNullOrEmpty()) exp &= SearchWhereByKeys(key);

View File

@ -161,12 +161,14 @@ public partial class User : Entity<User>
/// <param name="mobile">手机</param>
/// <param name="code">代码。身份证、员工编号等</param>
/// <param name="roleId">角色。主要角色</param>
/// <param name="areaId">地区。省市区</param>
/// <param name="enable">启用</param>
/// <param name="start">更新时间开始</param>
/// <param name="end">更新时间结束</param>
/// <param name="key">关键字</param>
/// <param name="page">分页参数信息。可携带统计和数据权限扩展查询等信息</param>
/// <returns>实体列表</returns>
public static IList<User> Search(String name, String? mail, String? mobile, String? code, Int32 roleId, DateTime start, DateTime end, String key, PageParameter page)
public static IList<User> Search(String name, String? mail, String? mobile, String? code, Int32 roleId, Int32 areaId, Boolean? enable, DateTime start, DateTime end, String key, PageParameter page)
{
var exp = new WhereExpression();
@ -175,6 +177,8 @@ public partial class User : Entity<User>
if (!mobile.IsNullOrEmpty()) exp &= _.Mobile == mobile;
if (!code.IsNullOrEmpty()) exp &= _.Code == code;
if (roleId >= 0) exp &= _.RoleID == roleId;
if (areaId >= 0) exp &= _.AreaId == areaId;
if (enable != null) exp &= _.Enable == enable;
exp &= _.UpdateTime.Between(start, end);
if (!key.IsNullOrEmpty()) exp &= SearchWhereByKeys(key);

View File

@ -121,16 +121,20 @@ public partial class Tenant : Entity<Tenant>
#region
/// <summary>高级查询</summary>
/// <param name="code">编码。唯一编码</param>
/// <param name="managerId">管理者</param>
/// <param name="enable">启用</param>
/// <param name="start">更新时间开始</param>
/// <param name="end">更新时间结束</param>
/// <param name="key">关键字</param>
/// <param name="page">分页参数信息。可携带统计和数据权限扩展查询等信息</param>
/// <returns>实体列表</returns>
public static IList<Tenant> Search(String? code, DateTime start, DateTime end, String key, PageParameter page)
public static IList<Tenant> Search(String? code, Int32 managerId, Boolean? enable, DateTime start, DateTime end, String key, PageParameter page)
{
var exp = new WhereExpression();
if (!code.IsNullOrEmpty()) exp &= _.Code == code;
if (managerId >= 0) exp &= _.ManagerId == managerId;
if (enable != null) exp &= _.Enable == enable;
exp &= _.UpdateTime.Between(start, end);
if (!key.IsNullOrEmpty()) exp &= SearchWhereByKeys(key);

View File

@ -119,17 +119,21 @@ public partial class TenantUser : Entity<TenantUser>
/// <summary>高级查询</summary>
/// <param name="tenantId">租户</param>
/// <param name="userId">用户</param>
/// <param name="roleId">角色。用户在该租户所对应的主要角色,替换用户自身的角色组</param>
/// <param name="enable">启用</param>
/// <param name="start">更新时间开始</param>
/// <param name="end">更新时间结束</param>
/// <param name="key">关键字</param>
/// <param name="page">分页参数信息。可携带统计和数据权限扩展查询等信息</param>
/// <returns>实体列表</returns>
public static IList<TenantUser> Search(Int32 tenantId, Int32 userId, DateTime start, DateTime end, String key, PageParameter page)
public static IList<TenantUser> Search(Int32 tenantId, Int32 userId, Int32 roleId, Boolean? enable, DateTime start, DateTime end, String key, PageParameter page)
{
var exp = new WhereExpression();
if (tenantId >= 0) exp &= _.TenantId == tenantId;
if (userId >= 0) exp &= _.UserId == userId;
if (roleId >= 0) exp &= _.RoleId == roleId;
if (enable != null) exp &= _.Enable == enable;
exp &= _.UpdateTime.Between(start, end);
if (!key.IsNullOrEmpty()) exp &= SearchWhereByKeys(key);

View File

@ -135,16 +135,18 @@ public partial class Role : Entity<Role>
#region
/// <summary>高级查询</summary>
/// <param name="name">名称</param>
/// <param name="enable">启用</param>
/// <param name="start">更新时间开始</param>
/// <param name="end">更新时间结束</param>
/// <param name="key">关键字</param>
/// <param name="page">分页参数信息。可携带统计和数据权限扩展查询等信息</param>
/// <returns>实体列表</returns>
public static IList<Role> Search(String name, DateTime start, DateTime end, String key, PageParameter page)
public static IList<Role> Search(String name, Boolean? enable, DateTime start, DateTime end, String key, PageParameter page)
{
var exp = new WhereExpression();
if (!name.IsNullOrEmpty()) exp &= _.Name == name;
if (enable != null) exp &= _.Enable == enable;
exp &= _.UpdateTime.Between(start, end);
if (!key.IsNullOrEmpty()) exp &= SearchWhereByKeys(key);

View File

@ -135,12 +135,14 @@ public partial class Department : Entity<Department>
/// <param name="code">代码</param>
/// <param name="name">名称</param>
/// <param name="parentId">父级</param>
/// <param name="managerId">管理者</param>
/// <param name="enable">启用</param>
/// <param name="start">更新时间开始</param>
/// <param name="end">更新时间结束</param>
/// <param name="key">关键字</param>
/// <param name="page">分页参数信息。可携带统计和数据权限扩展查询等信息</param>
/// <returns>实体列表</returns>
public static IList<Department> Search(Int32 tenantId, String? code, String name, Int32 parentId, DateTime start, DateTime end, String key, PageParameter page)
public static IList<Department> Search(Int32 tenantId, String? code, String name, Int32 parentId, Int32 managerId, Boolean? enable, DateTime start, DateTime end, String key, PageParameter page)
{
var exp = new WhereExpression();
@ -148,6 +150,8 @@ public partial class Department : Entity<Department>
if (!code.IsNullOrEmpty()) exp &= _.Code == code;
if (!name.IsNullOrEmpty()) exp &= _.Name == name;
if (parentId >= 0) exp &= _.ParentID == parentId;
if (managerId >= 0) exp &= _.ManagerId == managerId;
if (enable != null) exp &= _.Enable == enable;
exp &= _.UpdateTime.Between(start, end);
if (!key.IsNullOrEmpty()) exp &= SearchWhereByKeys(key);

View File

@ -157,12 +157,14 @@ public partial class User : Entity<User>
/// <param name="code">代码。身份证、员工编码等,支持登录</param>
/// <param name="roleId">角色。主要角色</param>
/// <param name="departmentId">部门。组织机构</param>
/// <param name="areaId">地区。省市区</param>
/// <param name="enable">启用</param>
/// <param name="start">更新时间开始</param>
/// <param name="end">更新时间结束</param>
/// <param name="key">关键字</param>
/// <param name="page">分页参数信息。可携带统计和数据权限扩展查询等信息</param>
/// <returns>实体列表</returns>
public static IList<User> Search(String name, String? mail, String? mobile, String? code, Int32 roleId, Int32 departmentId, DateTime start, DateTime end, String key, PageParameter page)
public static IList<User> Search(String name, String? mail, String? mobile, String? code, Int32 roleId, Int32 departmentId, Int32 areaId, Boolean? enable, DateTime start, DateTime end, String key, PageParameter page)
{
var exp = new WhereExpression();
@ -172,6 +174,8 @@ public partial class User : Entity<User>
if (!code.IsNullOrEmpty()) exp &= _.Code == code;
if (roleId >= 0) exp &= _.RoleID == roleId;
if (departmentId >= 0) exp &= _.DepartmentID == departmentId;
if (areaId >= 0) exp &= _.AreaId == areaId;
if (enable != null) exp &= _.Enable == enable;
exp &= _.UpdateTime.Between(start, end);
if (!key.IsNullOrEmpty()) exp &= SearchWhereByKeys(key);