From 18aae2464821d5e4b6342a9c9bd1f5b2399b3541 Mon Sep 17 00:00:00 2001 From: sunkaixuna <610262374@qq.com> Date: Sat, 24 Apr 2021 03:20:01 +0800 Subject: [PATCH] Add a configuration table query --- .../SqlServerTest/Demo/Demo1_Queryable.cs | 40 ++++++++++++- Src/Asp.Net/SqlServerTest/Models/OrderItem.cs | 14 +++++ .../SugarProvider/SqlSugarAccessory.cs | 15 +++++ Src/Asp.Net/SqlSugar/Entities/ConfigQuery.cs | 59 +++++++++++++++++++ .../ExpressionsToSql/Common/ExpressionTool.cs | 19 ++++++ .../DbMethods/SqlFuncExtendsion.cs | 22 +++++++ .../MethodCallExpressionResolve.cs | 57 ++++++++++++++++++ .../SqlSugar/Interface/ISqlSugarClient.cs | 2 +- Src/Asp.Net/SqlSugar/SqlSugar.csproj | 2 + Src/Asp.Net/SqlSugar/SqlSugarClient.cs | 2 +- 10 files changed, 229 insertions(+), 3 deletions(-) create mode 100644 Src/Asp.Net/SqlSugar/Entities/ConfigQuery.cs create mode 100644 Src/Asp.Net/SqlSugar/ExpressionsToSql/DbMethods/SqlFuncExtendsion.cs diff --git a/Src/Asp.Net/SqlServerTest/Demo/Demo1_Queryable.cs b/Src/Asp.Net/SqlServerTest/Demo/Demo1_Queryable.cs index 6d0326eb6..6fde8452d 100644 --- a/Src/Asp.Net/SqlServerTest/Demo/Demo1_Queryable.cs +++ b/Src/Asp.Net/SqlServerTest/Demo/Demo1_Queryable.cs @@ -5,7 +5,6 @@ using System.Data; using System.Dynamic; using System.Linq; using System.Text; - namespace OrmTest { public class Demo1_Queryable @@ -22,6 +21,45 @@ namespace OrmTest SqlFuncTest(); Subquery(); ReturnType(); + ConfiQuery(); + } + + private static void ConfiQuery() + { + var db = GetInstance(); + db.SqlConfigTable.SetKeyValue(it=>it.Id ,it=>it.Name,"01",it=>it.Id>1); + db.SqlConfigTable.SetKeyValue(it => it.Id, it => it.Name, "02", it => it.Id > 2); + db.SqlConfigTable.SetKeyValue(it => it.Id, it => it.Name,null); + var list = db.Queryable().Select(it => new OrderItem + { + ItemId = SqlFunc.GetSelfAndAutoFill(it.ItemId), + OrderName = it.OrderId.GetConfigValue("01") + }).ToList(); + var list2 = db.Queryable().Select(it => new OrderItem + { + ItemId = SqlFunc.GetSelfAndAutoFill(it.ItemId), + OrderName = it.OrderId.GetConfigValue("02") + }).ToList(); + var list3 = db.Queryable().Select(it => new OrderItem + { + ItemId = SqlFunc.GetSelfAndAutoFill(it.ItemId), + OrderName = it.OrderId.GetConfigValue() + }).ToList(); + + var list4 = db.Queryable().Select(it => new OrderItem + { + ItemId = SqlFunc.GetSelfAndAutoFill(it.ItemId), + OrderName = it.OrderId.GetConfigValue() + }) + .Where(it=>it.OrderId.GetConfigValue()=="jack") + .OrderBy(it=>it.OrderId.GetConfigValue()).ToList(); + + var list5 = db.Queryable((o, i, c) => o.Id == i.OrderId && c.Id == o.CustomId) + .Select((o,i,c)=>new ViewOrder() { + Id=SqlFunc.GetSelfAndAutoFill(o.Id), + Name=i.OrderId.GetConfigValue() + }) + .ToList(); } private static void EasyExamples() diff --git a/Src/Asp.Net/SqlServerTest/Models/OrderItem.cs b/Src/Asp.Net/SqlServerTest/Models/OrderItem.cs index ae3262c7c..7401b81a1 100644 --- a/Src/Asp.Net/SqlServerTest/Models/OrderItem.cs +++ b/Src/Asp.Net/SqlServerTest/Models/OrderItem.cs @@ -14,5 +14,19 @@ namespace OrmTest public decimal? Price { get; set; } [SqlSugar.SugarColumn(IsNullable = true)] public DateTime? CreateTime { get; set; } + [SqlSugar.SugarColumn(IsNullable = true)] + public string OrderName { get; set; } + } + [SqlSugar.SugarTable("OrderDetail")] + public class VOrderItem + { + [SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + public int ItemId { get; set; } + public int OrderId { get; set; } + public decimal? Price { get; set; } + [SqlSugar.SugarColumn(IsNullable = true)] + public DateTime? CreateTime { get; set; } + [SqlSugar.SugarColumn(IsIgnore = true)] + public string OrderName { get; set; } } } diff --git a/Src/Asp.Net/SqlSugar/Abstract/SugarProvider/SqlSugarAccessory.cs b/Src/Asp.Net/SqlSugar/Abstract/SugarProvider/SqlSugarAccessory.cs index 10c0e6268..bc7c0e2b6 100644 --- a/Src/Asp.Net/SqlSugar/Abstract/SugarProvider/SqlSugarAccessory.cs +++ b/Src/Asp.Net/SqlSugar/Abstract/SugarProvider/SqlSugarAccessory.cs @@ -31,6 +31,20 @@ namespace SqlSugar public MappingColumnList MappingColumns { get; set; } public IgnoreColumnList IgnoreColumns { get; set; } public IgnoreColumnList IgnoreInsertColumns { get; set; } + public SqlConfigTable SqlConfigTable { + get + { + if (_SqlConfigTable==null) + { + _SqlConfigTable = new SqlConfigTable() { Context = this.Context }; + } + return _SqlConfigTable; + } + set + { + _SqlConfigTable = value; + } + } #endregion @@ -46,6 +60,7 @@ namespace SqlSugar protected IContextMethods _RewritableMethods; protected IDbMaintenance _DbMaintenance; protected QueryFilterProvider _QueryFilterProvider; + protected SqlConfigTable _SqlConfigTable; //protected SimpleClient _SimpleClient; protected IAdo ContextAdo { diff --git a/Src/Asp.Net/SqlSugar/Entities/ConfigQuery.cs b/Src/Asp.Net/SqlSugar/Entities/ConfigQuery.cs new file mode 100644 index 000000000..483a46ed4 --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Entities/ConfigQuery.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; +namespace SqlSugar +{ + public class SqlConfigTable + { + public SqlSugarProvider Context { get; set; } + public void SetKeyValue(Expression> keyExpression, Expression> valueExpression, string uniqueCode = null, Expression> whereExpression=null) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + ExpressionContext context = new ExpressionContext(); + var query = Context.Queryable().QueryBuilder; + var keyValue= query.GetExpressionValue(keyExpression, ResolveExpressType.FieldSingle).GetString(); + var ValueValue = query.GetExpressionValue(valueExpression, ResolveExpressType.FieldSingle).GetString(); + string where = null; + if (whereExpression != null) + { + where=query.GetExpressionValue(whereExpression, ResolveExpressType.WhereSingle).GetResultString(); + } + context.MappingTables = this.Context.MappingTables; + if (!SqlFuncExtendsion.TableInfos.Any(y => y.Type == typeof(T) && y.Code == uniqueCode)) + { + SqlFuncExtendsion.TableInfos.Add(new ConfigTableInfo() + { + Type = typeof(T), + TableName = entity.DbTableName, + Key = keyValue, + Value = ValueValue, + Where = where, + Parameter = query.Parameters, + Code = uniqueCode + }); + } + else + { + Check.Exception(true, "SetKeyValue error , entity & uniqueCode already exist"); + } + } + public void SetKeyValue(Expression> key, Expression> value) + { + SetKeyValue(key,value, null,null); + } + } + + public class ConfigTableInfo + { + public string Code { get; set; } + public Type Type { get; set; } + public string TableName { get; set; } + public string Key { get; set; } + public string Value { get; set; } + public string Where { get; set; } + public List Parameter { get; set; } + } +} diff --git a/Src/Asp.Net/SqlSugar/ExpressionsToSql/Common/ExpressionTool.cs b/Src/Asp.Net/SqlSugar/ExpressionsToSql/Common/ExpressionTool.cs index df7cc9bdd..7217d9910 100644 --- a/Src/Asp.Net/SqlSugar/ExpressionsToSql/Common/ExpressionTool.cs +++ b/Src/Asp.Net/SqlSugar/ExpressionsToSql/Common/ExpressionTool.cs @@ -171,6 +171,25 @@ namespace SqlSugar return reval; } + internal static object GetExpressionValue(Expression expression) + { + try + { + if (expression is ConstantExpression) + { + return (expression as ConstantExpression).Value; + } + else + { + return GetMemberValue((expression as MemberExpression).Member, expression); + } + } + catch + { + return LambdaExpression.Lambda(expression).Compile().DynamicInvoke(); + } + } + public static object GetFiledValue(MemberExpression memberExpr) { if (!(memberExpr.Member is FieldInfo)) diff --git a/Src/Asp.Net/SqlSugar/ExpressionsToSql/DbMethods/SqlFuncExtendsion.cs b/Src/Asp.Net/SqlSugar/ExpressionsToSql/DbMethods/SqlFuncExtendsion.cs new file mode 100644 index 000000000..fcae85eab --- /dev/null +++ b/Src/Asp.Net/SqlSugar/ExpressionsToSql/DbMethods/SqlFuncExtendsion.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public static class SqlFuncExtendsion + { + internal static List TableInfos = new List(); + public static string GetConfigValue(this object field) + { + throw new NotSupportedException("Can only be used in expressions"); + } + public static string GetConfigValue(this object field,string uniqueCode) + { + throw new NotSupportedException("Can only be used in expressions"); + } + } +} \ No newline at end of file diff --git a/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs b/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs index 5eb9e5e81..89e03f72d 100644 --- a/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs +++ b/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs @@ -46,6 +46,11 @@ namespace SqlSugar this.Context.Result.Append(this.Context.DbMehtods.GuidNew()); return; } + else if (methodName == "GetConfigValue") + { + GetConfigValue(express,parameter); + return; + } else if (IsSubMethod(express, methodName)) { //Check.Exception(!(parameter.BaseExpression is BinaryExpression), "Current expressions are not supported"); @@ -95,6 +100,58 @@ namespace SqlSugar } } + private void GetConfigValue(MethodCallExpression express,ExpressionParameter parameter) + { + var exp = express.Arguments[0]; + var name =Regex.Match(express.Method.ToString(), @"GetConfigValue\[(.+)\]").Groups[1].Value; + string code = null; + if (express.Arguments.Count > 1) + { + code=ExpressionTool.GetExpressionValue(express.Arguments[1])+""; + } + var entity= SqlFuncExtendsion.TableInfos.FirstOrDefault(y => y.Type.Name == name&&y.Code== code); + Check.Exception(entity == null,string.Format( "GetConfigValue no configuration Entity={0} UniqueCode={1}",name,code)); + string sql = " (SELECT {0} FROM {1} WHERE {2}={3}"; + if (ExpressionTool.IsUnConvertExpress(exp)) + { + exp = (exp as UnaryExpression).Operand; + } + var member = exp as MemberExpression; + var it = member.Expression; + var type = it.Type; + var properyName =member.Member.Name; + var eqName = string.Format("{0}.{1}",this.Context.GetTranslationColumnName(it.ToString()), this.Context.GetDbColumnName(type.Name,properyName)); + if (this.Context.IsSingle) + { + this.Context.SingleTableNameSubqueryShortName = it.ToString(); + } + sql = string.Format(sql,entity.Value,this.Context.GetTranslationColumnName(entity.TableName),entity.Key, eqName); + if (entity.Parameter != null) + { + foreach (var item in entity.Parameter) + { + var oldName = item.ParameterName; + item.ParameterName = oldName + "_con_" + this.Context.ParameterIndex; + entity.Where = entity.Where.Replace(oldName, item.ParameterName); + } + this.Context.ParameterIndex++; + this.Context.Parameters.AddRange(entity.Parameter); + } + if (entity.Where.HasValue()) + { + sql += " AND " + entity.Where; + } + sql += " )"; + if (this.Context.ResolveType.IsIn(ResolveExpressType.SelectMultiple, ResolveExpressType.SelectSingle, ResolveExpressType.Update)) + { + parameter.BaseParameter.CommonTempData = sql; + } + else + { + AppendMember(parameter, parameter.IsLeft, sql); + } + } + private bool IsValidNativeMethod(MethodCallExpression express, string methodName) { return MethodMapping.ContainsKey(methodName) && express.Method.DeclaringType.Namespace == ("System"); diff --git a/Src/Asp.Net/SqlSugar/Interface/ISqlSugarClient.cs b/Src/Asp.Net/SqlSugar/Interface/ISqlSugarClient.cs index a0999fd0a..132c5ad67 100644 --- a/Src/Asp.Net/SqlSugar/Interface/ISqlSugarClient.cs +++ b/Src/Asp.Net/SqlSugar/Interface/ISqlSugarClient.cs @@ -13,7 +13,7 @@ namespace SqlSugar IgnoreColumnList IgnoreColumns { get; set; } IgnoreColumnList IgnoreInsertColumns { get; set; } Dictionary TempItems { get; set; } - + SqlConfigTable SqlConfigTable { get; set; } bool IsSystemTablesConfig { get; } Guid ContextID { get; set; } diff --git a/Src/Asp.Net/SqlSugar/SqlSugar.csproj b/Src/Asp.Net/SqlSugar/SqlSugar.csproj index 2903c59c8..d117a3972 100644 --- a/Src/Asp.Net/SqlSugar/SqlSugar.csproj +++ b/Src/Asp.Net/SqlSugar/SqlSugar.csproj @@ -89,10 +89,12 @@ + + diff --git a/Src/Asp.Net/SqlSugar/SqlSugarClient.cs b/Src/Asp.Net/SqlSugar/SqlSugarClient.cs index cd962b622..299ee6cfe 100644 --- a/Src/Asp.Net/SqlSugar/SqlSugarClient.cs +++ b/Src/Asp.Net/SqlSugar/SqlSugarClient.cs @@ -52,7 +52,7 @@ namespace SqlSugar public bool IsSystemTablesConfig => this.Context.IsSystemTablesConfig; public ConnectionConfig CurrentConnectionConfig { get { return _CurrentConnectionConfig; } set { _CurrentConnectionConfig = value; } } public Guid ContextID { get { return this.Context.ContextID; } set { this.Context.ContextID = value; } } - + public SqlConfigTable SqlConfigTable { get { return this.Context.SqlConfigTable; } set { this.Context.SqlConfigTable = value; } } public MappingTableList MappingTables { get { return _MappingTables; } set { _MappingTables = value; } } public MappingColumnList MappingColumns { get { return _MappingColumns; } set { _MappingColumns = value; } }