From f6e387ea25de383e664ea5e5b2faf53834c3e3a1 Mon Sep 17 00:00:00 2001 From: sunkaixuan <610262374@qq.com> Date: Sat, 5 May 2018 18:27:54 +0800 Subject: [PATCH] Update Core --- .../Abstract/AdoProvider/AdoProvider.cs | 5 +- .../IDataReaderEntityBuilder.cs | 7 ++ .../DbBindProvider/IDataRecordExtensions.cs | 13 +++ .../Abstract/DbMaintenanceProvider/Methods.cs | 19 ++-- .../InsertableProvider/InsertableProvider.cs | 61 +++++++++---- .../QueryableProvider/QueryableProvider.cs | 15 +++- .../SqlBuilderProvider/SqlBuilderProvider.cs | 10 +++ .../UpdateProvider/UpdateableProvider.cs | 85 ++++++++++++++---- .../SqlSugar/CacheScheme/CacheKeyBuider.cs | 1 + .../SqlSugar/Entities/PageModel.cs | 3 + .../SqlSugar/Enum/ConditionalType.cs | 3 +- .../ExpressionsToSql/DbMethods/SqlFunc.cs | 2 +- .../SqlSugar/Infrastructure/ContextMethods.cs | 7 ++ .../SqlSugar/Interface/ISqlBuilder.cs | 3 + .../SqlSugar/Interface/IUpdateable.cs | 9 ++ .../MySql/CodeFirst/MySqlCodeFirst.cs | 5 +- .../Realization/MySql/DbBind/MySqlDbBind.cs | 1 + .../MySql/DbMaintenance/MySqlDbMaintenance.cs | 39 ++++++-- .../Realization/MySql/MySqlProvider.cs | 2 +- .../SqlBuilder/OracleExpressionContext.cs | 7 ++ .../SqlServer/SqlServerProvider.cs | 2 +- .../Realization/Sqlite/SqliteProvider.cs | 2 +- .../SqlSeverTest/SqlSugar/SimpleClient.cs | 70 ++++++++++++--- .../SqlSeverTest/SqlSugar/SqlSugar.csproj | 2 +- .../SqlSeverTest/SqlSugar/SqlSugarClient.cs | 34 ++++++- .../SqlSugar/Utilities/UtilMethods.cs | 11 +++ .../SqliteTest/DataBase/SqlSugar4xTest.sqlite | Bin 282624 -> 307200 bytes 27 files changed, 348 insertions(+), 70 deletions(-) diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/AdoProvider/AdoProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/AdoProvider/AdoProvider.cs index 41891ab39..f89c140d3 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/AdoProvider/AdoProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/AdoProvider/AdoProvider.cs @@ -655,7 +655,10 @@ namespace SqlSugar { foreach (var outputParameter in parameters.Where(it => it.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput,ParameterDirection.ReturnValue))) { - var gobalOutputParamter = this.OutputParameters.Single(it => it.ParameterName == outputParameter.ParameterName); + var gobalOutputParamter = this.OutputParameters.FirstOrDefault(it => it.ParameterName == outputParameter.ParameterName); + if (gobalOutputParamter == null) {//Oracle bug + gobalOutputParamter=this.OutputParameters.FirstOrDefault(it => it.ParameterName == outputParameter.ParameterName.TrimStart(outputParameter.ParameterName.First())); + } outputParameter.Value = gobalOutputParamter.Value; this.OutputParameters.Remove(gobalOutputParamter); } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/IDataReaderEntityBuilder.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/IDataReaderEntityBuilder.cs index 941d837d3..1bfc9dec1 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/IDataReaderEntityBuilder.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/IDataReaderEntityBuilder.cs @@ -49,6 +49,8 @@ namespace SqlSugar private static readonly MethodInfo getConvertByte = typeof(IDataRecordExtensions).GetMethod("GetConvertByte"); private static readonly MethodInfo getConvertChar = typeof(IDataRecordExtensions).GetMethod("GetConvertChar"); private static readonly MethodInfo getConvertDateTime = typeof(IDataRecordExtensions).GetMethod("GetConvertDateTime"); + private static readonly MethodInfo getConvertTime = typeof(IDataRecordExtensions).GetMethod("GetConvertTime"); + private static readonly MethodInfo getTime = typeof(IDataRecordExtensions).GetMethod("GetTime"); private static readonly MethodInfo getConvertDecimal = typeof(IDataRecordExtensions).GetMethod("GetConvertDecimal"); private static readonly MethodInfo getConvertDouble = typeof(IDataRecordExtensions).GetMethod("GetConvertDouble"); private static readonly MethodInfo getConvertGuid = typeof(IDataRecordExtensions).GetMethod("GetConvertGuid"); @@ -176,6 +178,9 @@ namespace SqlSugar MethodInfo method = null; Type bindPropertyType = UtilMethods.GetUnderType(bindProperty, ref isNullableType); string dbTypeName = UtilMethods.GetParenthesesValue(DataRecord.GetDataTypeName(ordinal)); + if (dbTypeName.IsNullOrEmpty()) { + dbTypeName = bindPropertyType.Name; + } string propertyName = bindProperty.Name; string validPropertyName = bind.GetPropertyTypeName(dbTypeName); validPropertyName = validPropertyName == "byte[]" ? "byteArray" : validPropertyName; @@ -245,6 +250,8 @@ namespace SqlSugar CheckType(bind.DateThrow, bindProperyTypeName, validPropertyName, propertyName); if (bindProperyTypeName == "datetime") method = isNullableType ? getConvertDateTime : getDateTime; + if (bindProperyTypeName == "datetime"&&dbTypeName == "time") + method = isNullableType ? getConvertTime : getTime; break; case CSharpDataType.@decimal: CheckType(bind.DecimalThrow, bindProperyTypeName, validPropertyName, propertyName); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/IDataRecordExtensions.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/IDataRecordExtensions.cs index 0fe08be3f..d0b434cd0 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/IDataRecordExtensions.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/IDataRecordExtensions.cs @@ -60,6 +60,19 @@ namespace SqlSugar } return result; } + public static DateTime? GetConvertTime(this IDataRecord dr, int i) + { + var result = dr.GetValue(i); + if (result == DBNull.Value) + { + return null; ; + } + return Convert.ToDateTime(result.ToString()); + } + public static DateTime GetTime(this IDataRecord dr, int i) + { + return Convert.ToDateTime(dr.GetValue(i).ToString()); + } public static decimal? GetConvertDecimal(this IDataRecord dr, int i) { diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbMaintenanceProvider/Methods.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbMaintenanceProvider/Methods.cs index 6a2be323f..5a71d5ea7 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbMaintenanceProvider/Methods.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbMaintenanceProvider/Methods.cs @@ -45,9 +45,9 @@ namespace SqlSugar cacheKey = GetCacheKey(cacheKey); var sql = string.Format(this.GetColumnInfosByTableNameSql, tableName); if (isCache) - return GetListOrCache(cacheKey, sql); + return GetListOrCache(cacheKey, sql).GroupBy(it=>it.DbColumnName).Select(it=>it.First()).ToList(); else - return this.Context.Ado.SqlQuery(sql); + return this.Context.Ado.SqlQuery(sql).GroupBy(it => it.DbColumnName).Select(it => it.First()).ToList(); } public virtual List GetIsIdentities(string tableName) @@ -82,8 +82,8 @@ namespace SqlSugar } public virtual bool IsAnyColumn(string tableName, string columnName) { - columnName = this.SqlBuilder.GetTranslationColumnName(columnName); - tableName = this.SqlBuilder.GetTranslationTableName(tableName); + columnName = this.SqlBuilder.GetNoTranslationColumnName(columnName); + tableName = this.SqlBuilder.GetNoTranslationColumnName(tableName); var isAny = IsAnyTable(tableName); Check.Exception(!isAny, string.Format("Table {0} does not exist", tableName)); var columns = GetColumnInfosByTableName(tableName); @@ -92,7 +92,7 @@ namespace SqlSugar } public virtual bool IsPrimaryKey(string tableName, string columnName) { - columnName = this.SqlBuilder.GetTranslationColumnName(columnName); + columnName = this.SqlBuilder.GetNoTranslationColumnName(columnName); var isAny = IsAnyTable(tableName); Check.Exception(!isAny, string.Format("Table {0} does not exist", tableName)); var columns = GetColumnInfosByTableName(tableName); @@ -101,7 +101,7 @@ namespace SqlSugar } public virtual bool IsIdentity(string tableName, string columnName) { - columnName = this.SqlBuilder.GetTranslationColumnName(columnName); + columnName = this.SqlBuilder.GetNoTranslationColumnName(columnName); var isAny = IsAnyTable(tableName); Check.Exception(!isAny, string.Format("Table {0} does not exist", tableName)); var columns = GetColumnInfosByTableName(tableName); @@ -257,8 +257,8 @@ namespace SqlSugar { string columnName = this.SqlBuilder.GetTranslationTableName(columnInfo.DbColumnName); tableName = this.SqlBuilder.GetTranslationTableName(tableName); - string dataType = columnInfo.DataType; string dataSize = GetSize(columnInfo); + string dataType = columnInfo.DataType; string nullType = columnInfo.IsNullable ? this.CreateTableNull : CreateTableNotNull; string primaryKey = null; string identity = null; @@ -277,6 +277,11 @@ namespace SqlSugar { dataSize = item.Length > 0 ? string.Format("({0})", "max") : null; } + else if (item.Length == 0 && item.DecimalDigits > 0) + { + item.Length = 10; + dataSize = string.Format("({0},{1})", item.Length, item.DecimalDigits); + } else if (item.Length > 0 && item.DecimalDigits == 0) { dataSize = item.Length > 0 ? string.Format("({0})", item.Length) : null; diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/InsertableProvider/InsertableProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/InsertableProvider/InsertableProvider.cs index 79fd40639..bc11b2d30 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/InsertableProvider/InsertableProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/InsertableProvider/InsertableProvider.cs @@ -264,27 +264,58 @@ namespace SqlSugar foreach (var item in InsertObjs) { List insertItem = new List(); - foreach (var column in EntityInfo.Columns) + if (item is Dictionary) { - if (column.IsIgnore || column.IsOnlyIgnoreInsert) continue; - var columnInfo = new DbColumnInfo() - { - Value = column.PropertyInfo.GetValue(item, null), - DbColumnName = GetDbColumnName(column.PropertyName), - PropertyName = column.PropertyName, - PropertyType = UtilMethods.GetUnderType(column.PropertyInfo), - TableId = i - }; - if (columnInfo.PropertyType.IsEnum()) - { - columnInfo.Value = Convert.ToInt64(columnInfo.Value); - } - insertItem.Add(columnInfo); + SetInsertItemByDic(i, item, insertItem); + } + else + { + SetInsertItemByEntity(i, item, insertItem); } this.InsertBuilder.DbColumnInfoList.AddRange(insertItem); ++i; } } + private void SetInsertItemByDic(int i, T item, List insertItem) + { + foreach (var column in item as Dictionary) + { + var columnInfo = new DbColumnInfo() + { + Value = column.Value, + DbColumnName = column.Key, + PropertyName = column.Key, + PropertyType = UtilMethods.GetUnderType(column.Value.GetType()), + TableId = i + }; + if (columnInfo.PropertyType.IsEnum()) + { + columnInfo.Value = Convert.ToInt64(columnInfo.Value); + } + insertItem.Add(columnInfo); + } + } + private void SetInsertItemByEntity(int i, T item, List insertItem) + { + foreach (var column in EntityInfo.Columns) + { + if (column.IsIgnore || column.IsOnlyIgnoreInsert) continue; + var columnInfo = new DbColumnInfo() + { + Value = column.PropertyInfo.GetValue(item, null), + DbColumnName = GetDbColumnName(column.PropertyName), + PropertyName = column.PropertyName, + PropertyType = UtilMethods.GetUnderType(column.PropertyInfo), + TableId = i + }; + if (columnInfo.PropertyType.IsEnum()) + { + columnInfo.Value = Convert.ToInt64(columnInfo.Value); + } + insertItem.Add(columnInfo); + } + } + private string GetDbColumnName(string propertyName) { if (!IsMappingColumns) diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs index 9915d6f72..450f65c02 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs @@ -167,6 +167,7 @@ namespace SqlSugar public virtual T InSingle(object pkValue) { + Check.Exception(this.QueryBuilder.SelectValue.HasValue(), "'InSingle' and' Select' can't be used together,You can use .Select(it=>...).Single(it.id==1)"); var list = In(pkValue).ToList(); if (list == null) return default(T); else return list.SingleOrDefault(); @@ -987,7 +988,9 @@ namespace SqlSugar { var isSingle = QueryBuilder.IsSingle(); var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); - return Min(lamResult.GetResultString()); + var result= Min(lamResult.GetResultString()); + QueryBuilder.SelectValue = null; + return result; } protected TResult _Avg(Expression expression) { @@ -999,13 +1002,17 @@ namespace SqlSugar { var isSingle = QueryBuilder.IsSingle(); var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); - return Max(lamResult.GetResultString()); + var reslut= Max(lamResult.GetResultString()); + QueryBuilder.SelectValue = null; + return reslut; } protected TResult _Sum(Expression expression) { var isSingle = QueryBuilder.IsSingle(); var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); - return Sum(lamResult.GetResultString()); + var reslut= Sum(lamResult.GetResultString()); + QueryBuilder.SelectValue = null; + return reslut; } protected ISugarQueryable _As(string tableName, string entityName) { @@ -1173,7 +1180,7 @@ namespace SqlSugar { if (result.HasValue()) { - if (entityType.GetTypeInfo().BaseType.HasValue() && entityType.GetTypeInfo().BaseType == UtilConstants.ModelType) + if (UtilMethods.GetRootBaseType(entityType).HasValue() &&UtilMethods.GetRootBaseType(entityType) == UtilConstants.ModelType) { foreach (var item in result) { diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/SqlBuilderProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/SqlBuilderProvider.cs index 84984b589..1a637a826 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/SqlBuilderProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/SqlBuilderProvider.cs @@ -86,10 +86,20 @@ namespace SqlSugar { return "t"; } + + + public string GetWhere(string fieldName,string conditionalType,int? parameterIndex=null) + { + return string.Format(" {0} {1} {2}{3} ",fieldName,conditionalType,this.SqlParameterKeyWord,fieldName+ parameterIndex); + } public virtual string GetUnionAllSql(List sqlList) { return string.Join("UNION ALL \r\n", sqlList); } + public virtual string GetUnionSql(List sqlList) + { + return string.Join("UNION \r\n", sqlList); + } public virtual void RepairReplicationParameters(ref string appendSql, SugarParameter[] parameters, int addIndex) { UtilMethods.RepairReplicationParameters(ref appendSql, parameters, addIndex); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs index 9d93aee2d..a159bdc25 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs @@ -141,7 +141,7 @@ namespace SqlSugar public IUpdateable UpdateColumns(Expression> columns) { var binaryExp = columns.Body as BinaryExpression; Check.Exception(!binaryExp.NodeType.IsIn(ExpressionType.Equal), "No support {0}", columns.ToString()); - Check.Exception(!(binaryExp.Left is MemberExpression), "No support {0}", columns.ToString()); + Check.Exception(!(binaryExp.Left is MemberExpression)&& !(binaryExp.Left is UnaryExpression), "No support {0}", columns.ToString()); Check.Exception(ExpressionTool.IsConstExpression(binaryExp.Left as MemberExpression), "No support {0}", columns.ToString()); var expResult = UpdateBuilder.GetExpressionValue(columns, ResolveExpressType.WhereSingle).GetResultString().Replace("))",") )").Replace("((", "( (").Trim().TrimStart('(').TrimEnd(')'); string key = SqlBuilder.GetNoTranslationColumnName(expResult); @@ -196,6 +196,26 @@ namespace SqlSugar return this; } + public IUpdateable Where(string whereSql, object parameters = null) + { + if (whereSql.HasValue()) { + UpdateBuilder.WhereValues.Add(whereSql); + } + if (parameters != null) { + UpdateBuilder.Parameters.AddRange(Context.Ado.GetParameters(parameters)); + } + return this; + } + + public IUpdateable Where(string fieldName,string conditionalType, object fieldValue) + { + var whereSql=this.SqlBuilder.GetWhere(fieldName, conditionalType,0); + this.Where(whereSql); + string parameterName = this.SqlBuilder.SqlParameterKeyWord + fieldName+ "0"; + this.UpdateBuilder.Parameters.Add(new SugarParameter(parameterName, fieldValue)); + return this; + } + public IUpdateable With(string lockString) { if (this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer) @@ -226,26 +246,59 @@ namespace SqlSugar foreach (var item in UpdateObjs) { List updateItem = new List(); - foreach (var column in EntityInfo.Columns) + var isDic = item is Dictionary; + if (isDic) { - var columnInfo = new DbColumnInfo() - { - Value = column.PropertyInfo.GetValue(item, null), - DbColumnName = GetDbColumnName(column.PropertyName), - PropertyName = column.PropertyName, - PropertyType = UtilMethods.GetUnderType(column.PropertyInfo), - TableId = i - }; - if (columnInfo.PropertyType.IsEnum()) - { - columnInfo.Value = Convert.ToInt64(columnInfo.Value); - } - updateItem.Add(columnInfo); + SetUpdateItemByDic(i, item, updateItem); + } + else + { + SetUpdateItemByEntity(i, item, updateItem); } - this.UpdateBuilder.DbColumnInfoList.AddRange(updateItem); ++i; } } + private void SetUpdateItemByDic(int i, T item, List updateItem) + { + foreach (var column in item as Dictionary) + { + var columnInfo = new DbColumnInfo() + { + Value = column.Value, + DbColumnName =column.Key, + PropertyName = column.Key, + PropertyType = UtilMethods.GetUnderType(column.Value.GetType()), + TableId = i + }; + if (columnInfo.PropertyType.IsEnum()) + { + columnInfo.Value = Convert.ToInt64(columnInfo.Value); + } + updateItem.Add(columnInfo); + } + this.UpdateBuilder.DbColumnInfoList.AddRange(updateItem); + } + private void SetUpdateItemByEntity(int i, T item, List updateItem) + { + foreach (var column in EntityInfo.Columns) + { + var columnInfo = new DbColumnInfo() + { + Value = column.PropertyInfo.GetValue(item, null), + DbColumnName = GetDbColumnName(column.PropertyName), + PropertyName = column.PropertyName, + PropertyType = UtilMethods.GetUnderType(column.PropertyInfo), + TableId = i + }; + if (columnInfo.PropertyType.IsEnum()) + { + columnInfo.Value = Convert.ToInt64(columnInfo.Value); + } + updateItem.Add(columnInfo); + } + this.UpdateBuilder.DbColumnInfoList.AddRange(updateItem); + } + private void PreToSql() { UpdateBuilder.PrimaryKeys = GetPrimaryKeys(); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/CacheScheme/CacheKeyBuider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/CacheScheme/CacheKeyBuider.cs index 80508c5b6..ecbb293d0 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/CacheScheme/CacheKeyBuider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/CacheScheme/CacheKeyBuider.cs @@ -27,6 +27,7 @@ namespace SqlSugar result.IdentificationList.Add(queryBuilder.PartitionByValue); result.IdentificationList.Add(queryBuilder.Take.ObjToString()); result.IdentificationList.Add(queryBuilder.Skip.ObjToString()); + result.IdentificationList.Add(queryBuilder.IsCount.ObjToString()); if (queryBuilder.Parameters.HasValue()) { foreach (var item in queryBuilder.Parameters) diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/PageModel.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/PageModel.cs index 6beb46fbd..4d510dcb5 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/PageModel.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/PageModel.cs @@ -10,6 +10,9 @@ namespace SqlSugar { public int PageIndex { get; set; } public int PageSize { get; set; } + /// + /// output + /// public int PageCount { get; set; } } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Enum/ConditionalType.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Enum/ConditionalType.cs index fd54bdc78..e998c5e8b 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Enum/ConditionalType.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Enum/ConditionalType.cs @@ -19,6 +19,7 @@ namespace SqlSugar LikeRight=9, NoEqual=10, IsNullOrEmpty=11, - IsNot=12 + IsNot=12, + NoLike = 13, } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/SqlFunc.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/SqlFunc.cs index 8d68265aa..265e3f157 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/SqlFunc.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/SqlFunc.cs @@ -100,7 +100,7 @@ namespace SqlSugar public static TResult AggregateAvg(TResult thisValue) { throw new NotSupportedException("Can only be used in expressions"); } public static TResult AggregateMin(TResult thisValue) { throw new NotSupportedException("Can only be used in expressions"); } public static TResult AggregateMax(TResult thisValue) { throw new NotSupportedException("Can only be used in expressions"); } - public static TResult AggregateCount(TResult thisValue) { throw new NotSupportedException("Can only be used in expressions"); } + public static int AggregateCount(int thisValue) { throw new NotSupportedException("Can only be used in expressions"); } public static TResult MappingColumn(TResult oldColumnName,string newColumnName) { throw new NotSupportedException("Can only be used in expressions"); } /// ///Example: new NewT(){name=SqlFunc.GetSelfAndAutoFill(it)} Generated SQL it.* diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/ContextMethods.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/ContextMethods.cs index 9dd134071..3214de044 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/ContextMethods.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/ContextMethods.cs @@ -346,6 +346,9 @@ namespace SqlSugar } string temp = " {0} {1} {2} {3} "; string parameterName = string.Format("{0}Conditional{1}{2}", sqlBuilder.SqlParameterKeyWord, item.FieldName, index); + if (parameterName.Contains(".")) { + parameterName = parameterName.Replace(".", "_"); + } switch (item.ConditionalType) { case ConditionalType.Equal: @@ -388,6 +391,10 @@ namespace SqlSugar builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "LIKE", parameterName); parameters.Add(new SugarParameter(parameterName, item.FieldValue + "%")); break; + case ConditionalType.NoLike: + builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), " NOT LIKE", parameterName); + parameters.Add(new SugarParameter(parameterName, item.FieldValue + "%")); + break; case ConditionalType.LikeRight: builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "LIKE", parameterName); parameters.Add(new SugarParameter(parameterName, "%" + item.FieldValue)); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ISqlBuilder.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ISqlBuilder.cs index d83b60b80..b866e0e5e 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ISqlBuilder.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ISqlBuilder.cs @@ -35,7 +35,10 @@ namespace SqlSugar string GetNoTranslationColumnName(string name); string GetPackTable(string sql,string shortName); string GetDefaultShortName(); + + string GetWhere(string fieldName, string conditionalType, int? parameterIndex = null); string GetUnionAllSql(List sqlList); + string GetUnionSql(List sqlList); void RepairReplicationParameters(ref string appendSql, SugarParameter[] parameters, int addIndex); } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IUpdateable.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IUpdateable.cs index e01176529..1a31c9292 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IUpdateable.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IUpdateable.cs @@ -18,6 +18,15 @@ namespace SqlSugar IUpdateable With(string lockString); IUpdateable Where(bool isNoUpdateNull,bool IsOffIdentity = false); IUpdateable Where(Expression> expression); + IUpdateable Where(string whereSql,object parameters=null); + /// + /// + /// + /// + /// for example : = + /// + /// + IUpdateable Where(string fieldName, string conditionalType, object fieldValue); /// /// Non primary key entity update function /// diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/CodeFirst/MySqlCodeFirst.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/CodeFirst/MySqlCodeFirst.cs index 1211bed19..26df6cb10 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/CodeFirst/MySqlCodeFirst.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/CodeFirst/MySqlCodeFirst.cs @@ -16,6 +16,8 @@ namespace SqlSugar { foreach (var item in entityInfo.Columns) { + if (item.IsIgnore) + continue; DbColumnInfo dbColumnInfo = this.EntityColumnToDbColumn(entityInfo, tableName, item); columns.Add(dbColumnInfo); } @@ -35,7 +37,8 @@ namespace SqlSugar IsNullable = item.IsNullable, DefaultValue = item.DefaultValue, ColumnDescription = item.ColumnDescription, - Length = item.Length + Length = item.Length, + DecimalDigits=item.DecimalDigits }; GetDbType(item, propertyType, result); if (result.DataType.Equals("varchar", StringComparison.CurrentCultureIgnoreCase) && result.Length == 0) diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/DbBind/MySqlDbBind.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/DbBind/MySqlDbBind.cs index 283f66886..c85e4268a 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/DbBind/MySqlDbBind.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/DbBind/MySqlDbBind.cs @@ -70,6 +70,7 @@ namespace SqlSugar new KeyValuePair("time",CSharpDataType.DateTime), new KeyValuePair("blob",CSharpDataType.byteArray), + new KeyValuePair("longblob",CSharpDataType.byteArray), new KeyValuePair("tinyblob",CSharpDataType.byteArray), new KeyValuePair("varbinary",CSharpDataType.byteArray), new KeyValuePair("binary",CSharpDataType.byteArray), diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/DbMaintenance/MySqlDbMaintenance.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/DbMaintenance/MySqlDbMaintenance.cs index 943c5eb12..99aee80a9 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/DbMaintenance/MySqlDbMaintenance.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/DbMaintenance/MySqlDbMaintenance.cs @@ -185,7 +185,7 @@ namespace SqlSugar { foreach (var item in columns) { - if (item.DbColumnName.Equals("GUID", StringComparison.CurrentCultureIgnoreCase) && item.Length == 0) + if (item.DbColumnName.Equals("GUID",StringComparison.CurrentCultureIgnoreCase)&&item.Length==0) { item.Length = 10; } @@ -193,9 +193,8 @@ namespace SqlSugar } string sql = GetCreateTableSql(tableName, columns); string primaryKeyInfo = null; - if (columns.Any(it => it.IsPrimarykey) && isCreatePrimaryKey) - { - primaryKeyInfo = string.Format(", Primary key({0})", string.Join(",", columns.Where(it => it.IsPrimarykey).Select(it => this.SqlBuilder.GetTranslationColumnName(it.DbColumnName)))); + if (columns.Any(it => it.IsPrimarykey)&&isCreatePrimaryKey) { + primaryKeyInfo =string.Format( ", Primary key({0})",string.Join(",",columns.Where(it=>it.IsPrimarykey).Select(it=>this.SqlBuilder.GetTranslationColumnName(it.DbColumnName)))); } sql = sql.Replace("$PrimaryKey", primaryKeyInfo); @@ -209,11 +208,9 @@ namespace SqlSugar foreach (var item in columns) { string columnName = item.DbColumnName; + string dataSize = ""; + dataSize = GetSize(item); string dataType = item.DataType; - if (dataType == "varchar"&& item.Length==0) { - item.Length = 1; - } - string dataSize = item.Length > 0 ? string.Format("({0})", item.Length) : null; string nullType = item.IsNullable ? this.CreateTableNull : CreateTableNotNull; string primaryKey = null; string identity = item.IsIdentity ? this.CreateTableIdentity : null; @@ -223,6 +220,32 @@ namespace SqlSugar string tableString = string.Format(this.CreateTableSql, this.SqlBuilder.GetTranslationTableName(tableName), string.Join(",\r\n", columnArray)); return tableString; } + + protected override string GetSize(DbColumnInfo item) + { + string dataSize = null; + var isMax = item.Length > 4000 || item.Length == -1; + if (isMax) + { + dataSize=""; + item.DataType = "longtext"; + } + else if (item.Length > 0 && item.DecimalDigits == 0) + { + dataSize = item.Length > 0 ? string.Format("({0})", item.Length) : null; + } + else if (item.Length == 0 && item.DecimalDigits > 0) + { + item.Length = 10; + dataSize = string.Format("({0},{1})", item.Length, item.DecimalDigits); + } + else if (item.Length > 0 && item.DecimalDigits > 0) + { + dataSize = item.Length > 0 ? string.Format("({0},{1})", item.Length, item.DecimalDigits) : null; + } + return dataSize; + } + public override bool IsAnyConstraint(string constraintName) { throw new NotSupportedException("MySql IsAnyConstraint NotSupportedException"); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/MySqlProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/MySqlProvider.cs index fd3d240a4..b1f4c580e 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/MySqlProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/MySqlProvider.cs @@ -116,7 +116,7 @@ namespace SqlSugar sqlParameter.Direction = ParameterDirection.Input; } result[index] = sqlParameter; - if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput)) + if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue)) { if (this.OutputParameters == null) this.OutputParameters = new List(); this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Oracle/SqlBuilder/OracleExpressionContext.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Oracle/SqlBuilder/OracleExpressionContext.cs index a43964aeb..e39e4621e 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Oracle/SqlBuilder/OracleExpressionContext.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Oracle/SqlBuilder/OracleExpressionContext.cs @@ -45,6 +45,13 @@ namespace SqlSugar var parameter = model.Args[0]; return string.Format(" to_timestamp({0},'0000-01-01 hh24:mi:ss') ", parameter.MemberName); } + public override string Substring(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format("SUBSTR({0},1 + {1},{2})", parameter.MemberName, parameter2.MemberName, parameter3.MemberName); + } public override string DateValue(MethodCallExpressionModel model) { var parameter = model.Args[0]; diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/SqlServer/SqlServerProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/SqlServer/SqlServerProvider.cs index eb2f46dd6..b0a71799d 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/SqlServer/SqlServerProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/SqlServer/SqlServerProvider.cs @@ -98,7 +98,7 @@ namespace SqlSugar sqlParameter.DbType = parameter.DbType; sqlParameter.Direction = parameter.Direction; result[index] = sqlParameter; - if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput)) + if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput,ParameterDirection.ReturnValue)) { if (this.OutputParameters == null) this.OutputParameters = new List(); this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Sqlite/SqliteProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Sqlite/SqliteProvider.cs index 7cc4217af..0e39f1901 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Sqlite/SqliteProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Sqlite/SqliteProvider.cs @@ -94,7 +94,7 @@ namespace SqlSugar sqlParameter.Value = parameter.Value; sqlParameter.DbType = parameter.DbType; result[index] = sqlParameter; - if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput)) + if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput,ParameterDirection.ReturnValue)) { if (this.OutputParameters == null) this.OutputParameters = new List(); this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SimpleClient.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SimpleClient.cs index e0059f5ac..47e54f388 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SimpleClient.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SimpleClient.cs @@ -28,14 +28,25 @@ namespace SqlSugar { return Context.Queryable().ToList(); } + public T GetSingle(Expression> whereExpression) where T : class, new() + { + return Context.Queryable().Single(whereExpression); + } public List GetList(Expression> whereExpression) where T : class, new() { return Context.Queryable().Where(whereExpression).ToList(); } - public List GetPageList(Expression> whereExpression,PageModel page) where T : class, new() + public List GetPageList(Expression> whereExpression, PageModel page) where T : class, new() { int count = 0; - var result= Context.Queryable().Where(whereExpression).ToPageList(page.PageIndex,page.PageSize,ref count); + var result = Context.Queryable().Where(whereExpression).ToPageList(page.PageIndex, page.PageSize, ref count); + page.PageCount = count; + return result; + } + public List GetPageList(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc) where T : class, new() + { + int count = 0; + var result = Context.Queryable().OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(whereExpression).ToPageList(page.PageIndex, page.PageSize, ref count); page.PageCount = count; return result; } @@ -46,6 +57,13 @@ namespace SqlSugar page.PageCount = count; return result; } + public List GetPageList(List conditionalList, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc) where T : class, new() + { + int count = 0; + var result = Context.Queryable().OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(conditionalList).ToPageList(page.PageIndex, page.PageSize, ref count); + page.PageCount = count; + return result; + } public bool IsAny(Expression> whereExpression) where T : class, new() { return Context.Queryable().Where(whereExpression).Any(); @@ -70,6 +88,10 @@ namespace SqlSugar { return this.Context.Updateable(updateObj).ExecuteCommand() > 0; } + public bool UpdateRange(T[] updateObjs) where T : class, new() + { + return this.Context.Updateable(updateObjs).ExecuteCommand() > 0; + } public bool Update(Expression> columns, Expression> whereExpression) where T : class, new() { return this.Context.Updateable().UpdateColumns(columns).Where(whereExpression).ExecuteCommand() > 0; @@ -109,7 +131,7 @@ namespace SqlSugar { return Context.Queryable().InSingle(id); } - public List GetList() + public List GetList() { return Context.Queryable().ToList(); } @@ -117,6 +139,10 @@ namespace SqlSugar { return Context.Queryable().Where(whereExpression).ToList(); } + public T GetSingle(Expression> whereExpression) + { + return Context.Queryable().Single(whereExpression); + } public List GetPageList(Expression> whereExpression, PageModel page) { int count = 0; @@ -124,6 +150,13 @@ namespace SqlSugar page.PageCount = count; return result; } + public List GetPageList(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc) + { + int count = 0; + var result = Context.Queryable().OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(whereExpression).ToPageList(page.PageIndex, page.PageSize, ref count); + page.PageCount = count; + return result; + } public List GetPageList(List conditionalList, PageModel page) { int count = 0; @@ -131,19 +164,32 @@ namespace SqlSugar page.PageCount = count; return result; } + public List GetPageList(List conditionalList, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc) + { + int count = 0; + var result = Context.Queryable().OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(conditionalList).ToPageList(page.PageIndex, page.PageSize, ref count); + page.PageCount = count; + return result; + } public bool IsAny(Expression> whereExpression) { return Context.Queryable().Where(whereExpression).Any(); } - public bool Insert(T insertObj) + public int Count(Expression> whereExpression) + { + + return Context.Queryable().Where(whereExpression).Count(); + } + + public bool Insert(T insertObj) { return this.Context.Insertable(insertObj).ExecuteCommand() > 0; } - public int InsertReturnIdentity(T insertObj) + public int InsertReturnIdentity(T insertObj) { return this.Context.Insertable(insertObj).ExecuteReturnIdentity(); } - public bool InsertRange(T[] insertObjs) + public bool InsertRange(T[] insertObjs) { return this.Context.Insertable(insertObjs).ExecuteCommand() > 0; } @@ -151,11 +197,15 @@ namespace SqlSugar { return this.Context.Insertable(insertObjs).ExecuteCommand() > 0; } - public bool Update(T updateObj) + public bool Update(T updateObj) { return this.Context.Updateable(updateObj).ExecuteCommand() > 0; } - public bool Update(Expression> columns, Expression> whereExpression) + public bool UpdateRange(T [] updateObjs) + { + return this.Context.Updateable(updateObjs).ExecuteCommand() > 0; + } + public bool Update(Expression> columns, Expression> whereExpression) { return this.Context.Updateable().UpdateColumns(columns).Where(whereExpression).ExecuteCommand() > 0; } @@ -163,11 +213,11 @@ namespace SqlSugar { return this.Context.Deleteable().Where(deleteObj).ExecuteCommand() > 0; } - public bool Delete(Expression> whereExpression) + public bool Delete(Expression> whereExpression) { return this.Context.Deleteable().Where(whereExpression).ExecuteCommand() > 0; } - public bool DeleteById(dynamic id) + public bool DeleteById(dynamic id) { return this.Context.Deleteable().In(id).ExecuteCommand() > 0; } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugar.csproj b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugar.csproj index a93e98a5c..f610fab51 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugar.csproj +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugar.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 4.6.4.7 + 4.6.4.9 sun_kai_xuan https://github.com/sunkaixuan/SqlSugar diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs index 6473943d2..9510d19b5 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs @@ -38,7 +38,7 @@ namespace SqlSugar DependencyManagement.TryOracle(); break; case DbType.PostgreSQL: - throw new Exception("Development 50%"); + throw new Exception("开发中"); default: throw new Exception("ConnectionConfig.DbType is null"); } @@ -395,6 +395,34 @@ namespace SqlSugar Check.Exception(queryables.IsNullOrEmpty(), "UnionAll.queryables is null "); return UnionAll(queryables.ToArray()); } + public virtual ISugarQueryable Union(params ISugarQueryable[] queryables) where T : class, new() + { + var sqlBuilder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + Check.Exception(queryables.IsNullOrEmpty(), "UnionAll.queryables is null "); + int i = 1; + List>> allItems = new List>>(); + foreach (var item in queryables) + { + var sqlObj = item.ToSql(); + string sql = sqlObj.Key; + UtilMethods.RepairReplicationParameters(ref sql, sqlObj.Value.ToArray(), i); + if (sqlObj.Value.HasValue()) + allItems.Add(new KeyValuePair>(sql, sqlObj.Value)); + else + allItems.Add(new KeyValuePair>(sql, new List())); + i++; + } + var allSql = sqlBuilder.GetUnionSql(allItems.Select(it => it.Key).ToList()); + var allParameters = allItems.SelectMany(it => it.Value).ToArray(); + var resulut = this.Context.Queryable().AS(UtilMethods.GetPackTable(allSql, "unionTable")).With(SqlWith.Null); + resulut.AddParameters(allParameters); + return resulut.Select(sqlBuilder.SqlSelectAll); + } + public virtual ISugarQueryable Union(List> queryables) where T : class, new() + { + Check.Exception(queryables.IsNullOrEmpty(), "Union.queryables is null "); + return Union(queryables.ToArray()); + } #endregion #region SqlQueryable @@ -626,7 +654,9 @@ namespace SqlSugar } public virtual SimpleClient GetSimpleClient() { - return this.SimpleClient; + if (this.Context._SimpleClient == null) + this.Context._SimpleClient = new SimpleClient(this.Context); + return this.Context._SimpleClient; } #endregion diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilMethods.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilMethods.cs index 8caf4b847..410d6dd9a 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilMethods.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilMethods.cs @@ -17,6 +17,17 @@ namespace SqlSugar return type==null ? oldType : type; } + internal static Type GetRootBaseType(Type entityType) + { + var baseType = entityType.BaseType; + while (baseType != null && baseType.BaseType != UtilConstants.ObjType) + { + baseType = baseType.BaseType; + } + return baseType; + } + + internal static Type GetUnderType(PropertyInfo propertyInfo, ref bool isNullable) { Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqliteTest/DataBase/SqlSugar4xTest.sqlite b/Src/Asp.NetCore2/SqlSeverTest/SqliteTest/DataBase/SqlSugar4xTest.sqlite index 77e219d5d796a9f794832f10f52df0b444935bc9..556b823be37f2af014bcb05bc9f269fcbfcbcc1a 100644 GIT binary patch literal 307200 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 QqyJ-kf2c?Q$F=(Z1qtG^O8@`>