From 2b2a810b9c61dfb2de6528bc473fbab1ccb97bf6 Mon Sep 17 00:00:00 2001 From: sunkaixuan <610262374@qq.com> Date: Sun, 11 Nov 2018 21:08:35 +0800 Subject: [PATCH] Update Core --- .../CodeFirstProvider/CodeFirstProvider.cs | 17 ++++ .../Abstract/DbMaintenanceProvider/Methods.cs | 75 ++++++++++++++- .../DbMaintenanceProvider/Properties.cs | 6 ++ .../EntityMaintenance/EntityMaintenance.cs | 4 + .../QueryableProvider/QueryableProvider.cs | 90 ++++++++++++++++-- .../UpdateProvider/UpdateableProvider.cs | 33 ++++++- .../SqlSugar/CacheScheme/CacheKeyBuider.cs | 1 + .../SqlSugar/Entities/ConnectionConfig.cs | 1 + .../SqlSugar/Entities/EntityInfo.cs | 1 + .../Entities/Mapping/SugarMappingAttribute.cs | 6 ++ .../Common/ExpressionResult.cs | 25 +++-- .../ExpressionsToSql/Common/SugarParameter.cs | 4 + .../MemberInitExpressionResolve.cs | 2 +- .../ResolveItems/NewArrayExpessionResolve.cs | 4 +- .../SqlSugar/Infrastructure/ContextMethods.cs | 1 + .../Infrastructure/SqlSugarAccessory.cs | 11 ++- .../SqlSugar/Interface/ICodeFirst.cs | 1 + .../SqlSugar/Interface/IDbMaintenance.cs | 7 ++ .../SqlSugar/Interface/IQueryable.cs | 13 ++- .../SqlSugar/Interface/IUpdateable.cs | 4 + .../MySql/CodeFirst/MySqlCodeFirst.cs | 5 + .../MySql/DbMaintenance/MySqlDbMaintenance.cs | 63 ++++++++++++ .../DbMaintenance/OracleDbMaintenance.cs | 47 +++++++++ .../DbMaintenance/SqlServerDbMaintenance.cs | 64 +++++++++++++ .../DbMaintenance/SqliteDbMaintenance.cs | 51 ++++++++++ .../SqlSeverTest/SqlSugar/SqlSugarClient.cs | 34 +++---- .../SqlSugar/Utilities/UtilConstants.cs | 2 + .../SqlSugar/Utilities/UtilMethods.cs | 4 +- .../SqliteTest/DataBase/SqlSugar4xTest.sqlite | Bin 315392 -> 327680 bytes 29 files changed, 531 insertions(+), 45 deletions(-) diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/CodeFirstProvider/CodeFirstProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/CodeFirstProvider/CodeFirstProvider.cs index b75125131..9bbbb5886 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/CodeFirstProvider/CodeFirstProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/CodeFirstProvider/CodeFirstProvider.cs @@ -11,6 +11,7 @@ namespace SqlSugar public virtual SqlSugarClient Context { get; set; } private bool IsBackupTable { get; set; } private int MaxBackupDataRows { get; set; } + private int DefultLength { get; set; } #endregion #region Public methods @@ -20,6 +21,12 @@ namespace SqlSugar this.MaxBackupDataRows = maxBackupDataRows; return this; } + + public virtual ICodeFirst SetStringDefaultLength(int length) { + DefultLength = length; + return this; + } + public virtual void InitTables(Type entityType) { @@ -67,12 +74,22 @@ namespace SqlSugar protected virtual void Execute(Type entityType) { var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(entityType); + if (this.DefultLength > 0) { + foreach (var item in entityInfo.Columns) + { + if (item.PropertyInfo.PropertyType == UtilConstants.StringType && item.DataType.IsNullOrEmpty()&& item.Length==0) { + item.Length = DefultLength; + } + } + } var tableName = GetTableName(entityInfo); var isAny = this.Context.DbMaintenance.IsAnyTable(tableName); if (isAny) ExistLogic(entityInfo); else NoExistLogic(entityInfo); + + this.Context.DbMaintenance.AddRemark(entityInfo); } public virtual void NoExistLogic(EntityInfo entityInfo) { diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbMaintenanceProvider/Methods.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbMaintenanceProvider/Methods.cs index d4c198446..9dd10a69e 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbMaintenanceProvider/Methods.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbMaintenanceProvider/Methods.cs @@ -45,7 +45,7 @@ namespace SqlSugar cacheKey = GetCacheKey(cacheKey); var sql = string.Format(this.GetColumnInfosByTableNameSql, tableName); if (isCache) - return GetListOrCache(cacheKey, sql).GroupBy(it=>it.DbColumnName).Select(it=>it.First()).ToList(); + return GetListOrCache(cacheKey, sql).GroupBy(it => it.DbColumnName).Select(it => it.First()).ToList(); else return this.Context.Ado.SqlQuery(sql).GroupBy(it => it.DbColumnName).Select(it => it.First()).ToList(); @@ -208,6 +208,79 @@ namespace SqlSugar this.Context.Ado.ExecuteCommand(sql); return true; } + public virtual bool AddColumnRemark(string columnName, string tableName, string description) + { + string sql = string.Format(this.AddColumnRemarkSql, columnName, tableName, description); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool DeleteColumnRemark(string columnName, string tableName) + { + string sql = string.Format(this.DeleteColumnRemarkSql, columnName, tableName); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool IsAnyColumnRemark(string columnName, string tableName) + { + string sql = string.Format(this.IsAnyColumnRemarkSql, columnName, tableName); + var dt=this.Context.Ado.GetDataTable(sql); + return dt.Rows!=null&&dt.Rows.Count>0; + } + public virtual bool AddTableRemark(string tableName, string description) + { + string sql = string.Format(this.AddTableRemarkSql, tableName, description); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool DeleteTableRemark(string tableName) + { + string sql = string.Format(this.DeleteTableRemarkSql,tableName); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public virtual bool IsAnyTableRemark(string tableName) + { + string sql = string.Format(this.IsAnyTableRemarkSql, tableName); + var dt=this.Context.Ado.GetDataTable(sql); + return dt.Rows != null && dt.Rows.Count > 0; + } + public virtual bool AddRemark(EntityInfo entity) + { + var db = this.Context; + var columns = entity.Columns.Where(it => it.IsIgnore == false).ToList(); + + foreach (var item in columns) + { + if (item.ColumnDescription != null) + { + //column remak + if (db.DbMaintenance.IsAnyColumnRemark(item.DbColumnName, item.DbTableName)) + { + db.DbMaintenance.DeleteColumnRemark(item.DbColumnName, item.DbTableName); + db.DbMaintenance.AddColumnRemark(item.DbColumnName, item.DbTableName, item.ColumnDescription); + } + else + { + db.DbMaintenance.AddColumnRemark(item.DbColumnName, item.DbTableName, item.ColumnDescription); + } + } + } + + //table remak + if (entity.TableDescription != null) + { + if (db.DbMaintenance.IsAnyTableRemark(entity.DbTableName)) + { + db.DbMaintenance.DeleteTableRemark(entity.DbTableName); + db.DbMaintenance.AddTableRemark(entity.DbTableName, entity.TableDescription); + } + else + { + db.DbMaintenance.AddTableRemark(entity.DbTableName, entity.TableDescription); + } + } + return true; + } #endregion #region Private diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbMaintenanceProvider/Properties.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbMaintenanceProvider/Properties.cs index da9ac12b7..3bd7d27f7 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbMaintenanceProvider/Properties.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbMaintenanceProvider/Properties.cs @@ -43,6 +43,12 @@ namespace SqlSugar protected abstract string DropConstraintSql { get; } protected abstract string AddPrimaryKeySql { get; } protected abstract string RenameColumnSql { get; } + protected abstract string AddColumnRemarkSql { get; } + protected abstract string DeleteColumnRemarkSql { get; } + protected abstract string IsAnyColumnRemarkSql { get; } + protected abstract string AddTableRemarkSql { get; } + protected abstract string DeleteTableRemarkSql { get; } + protected abstract string IsAnyTableRemarkSql { get; } #endregion #region Check diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/EntityMaintenance/EntityMaintenance.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/EntityMaintenance/EntityMaintenance.cs index cd2bc6605..ab89467ee 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/EntityMaintenance/EntityMaintenance.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/EntityMaintenance/EntityMaintenance.cs @@ -27,6 +27,10 @@ namespace SqlSugar { var sugarTable = (SugarTable)sugarAttributeInfo; result.DbTableName = sugarTable.TableName; + result.TableDescription = sugarTable.TableDescription; + } + if (this.Context.Context.CurrentConnectionConfig.ConfigureExternalServices != null && this.Context.CurrentConnectionConfig.ConfigureExternalServices.EntityNameService != null) { + this.Context.CurrentConnectionConfig.ConfigureExternalServices.EntityNameService(type,result); } result.Type = type; result.EntityName = result.Type.Name; diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs index c37537820..ef0477cec 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs @@ -50,6 +50,12 @@ namespace SqlSugar QueryBuilder.Clear(); } + public ISugarQueryable Clone() + { + var queryable = this.Context.Queryable().WithCacheIF(IsCache, CacheTime); + CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } public virtual ISugarQueryable AS(string tableName) { var entityName = typeof(T2).Name; @@ -1264,23 +1270,28 @@ namespace SqlSugar } } } - private ISugarQueryable CopyQueryable() + protected ISugarQueryable CopyQueryable() { var asyncContext = this.Context.Utilities.CopyContext(true); asyncContext.CurrentConnectionConfig.IsAutoCloseConnection = true; + var asyncQueryable = asyncContext.Queryable().Select(string.Empty).WithCacheIF(IsCache, CacheTime); + CopyQueryBuilder(asyncQueryable.QueryBuilder); return asyncQueryable; + } - var asyncQueryable = asyncContext.Queryable().Select(string.Empty); - var asyncQueryableBuilder = asyncQueryable.QueryBuilder; + protected void CopyQueryBuilder(QueryBuilder asyncQueryableBuilder) + { + var pars = new List(); + pars.AddRange(this.QueryBuilder.Parameters); asyncQueryableBuilder.Take = this.QueryBuilder.Take; asyncQueryableBuilder.Skip = this.QueryBuilder.Skip; asyncQueryableBuilder.SelectValue = this.QueryBuilder.SelectValue; - asyncQueryableBuilder.WhereInfos = this.QueryBuilder.WhereInfos; + asyncQueryableBuilder.WhereInfos =this.Context.Utilities.TranslateCopy(this.QueryBuilder.WhereInfos); asyncQueryableBuilder.EasyJoinInfos = this.QueryBuilder.EasyJoinInfos; asyncQueryableBuilder.JoinQueryInfos = this.QueryBuilder.JoinQueryInfos; asyncQueryableBuilder.WhereIndex = this.QueryBuilder.WhereIndex; asyncQueryableBuilder.EntityType = this.QueryBuilder.EntityType; asyncQueryableBuilder.EntityName = this.QueryBuilder.EntityName; - asyncQueryableBuilder.Parameters = this.QueryBuilder.Parameters; + asyncQueryableBuilder.Parameters = pars; asyncQueryableBuilder.TableShortName = this.QueryBuilder.TableShortName; asyncQueryableBuilder.TableWithString = this.QueryBuilder.TableWithString; asyncQueryableBuilder.GroupByValue = this.QueryBuilder.GroupByValue; @@ -1288,7 +1299,8 @@ namespace SqlSugar asyncQueryableBuilder.IsDisabledGobalFilter = this.QueryBuilder.IsDisabledGobalFilter; asyncQueryableBuilder.PartitionByValue = this.QueryBuilder.PartitionByValue; asyncQueryableBuilder.JoinExpression = this.QueryBuilder.JoinExpression; - return asyncQueryable; + asyncQueryableBuilder.WhereIndex = this.QueryBuilder.WhereIndex; + asyncQueryableBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; } #endregion } @@ -1460,6 +1472,12 @@ namespace SqlSugar #endregion #region Other + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t,t2)=>new object[] { }).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } public new ISugarQueryable AS(string tableName) { var entityName = typeof(AsT).Name; @@ -1737,6 +1755,12 @@ namespace SqlSugar #endregion #region Other + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2,t3) => new object[] { }).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } public new ISugarQueryable AS(string tableName) { var entityName = typeof(AsT).Name; @@ -2046,6 +2070,12 @@ namespace SqlSugar #endregion #region Other + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2,t3,t4) => new object[] { }).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } public new ISugarQueryable AS(string tableName) { var entityName = typeof(AsT).Name; @@ -2358,6 +2388,12 @@ namespace SqlSugar #endregion #region Other + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4,t5) => new object[] { }).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } public new ISugarQueryable AS(string tableName) { var entityName = typeof(AsT).Name; @@ -2660,6 +2696,12 @@ namespace SqlSugar #endregion #region Other + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4, t5,T6) => new object[] { }).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } public new ISugarQueryable AS(string tableName) { var entityName = typeof(AsT).Name; @@ -2989,6 +3031,12 @@ namespace SqlSugar #endregion #region Other + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4, t5, T6,t7) => new object[] { }).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } public new ISugarQueryable AS(string tableName) { var entityName = typeof(AsT).Name; @@ -3344,6 +3392,12 @@ namespace SqlSugar #endregion #region Other + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4, t5, T6, t7,t8) => new object[] { }).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } public new ISugarQueryable AS(string tableName) { var entityName = typeof(AsT).Name; @@ -3723,6 +3777,12 @@ namespace SqlSugar #endregion #region Other + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4, t5, T6, t7, t8,t9) => new object[] { }).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } public new ISugarQueryable AS(string tableName) { var entityName = typeof(AsT).Name; @@ -4126,6 +4186,12 @@ namespace SqlSugar #endregion #region Other + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4, t5, T6, t7, t8, t9,t10) => new object[] { }).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } public new ISugarQueryable AS(string tableName) { var entityName = typeof(AsT).Name; @@ -4553,6 +4619,12 @@ namespace SqlSugar #endregion #region Other + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4, t5, T6, t7, t8, t9,t10,t11) => new object[] { }).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } public new ISugarQueryable AS(string tableName) { var entityName = typeof(AsT).Name; @@ -5006,6 +5078,12 @@ namespace SqlSugar #endregion #region Other + public new ISugarQueryable Clone() + { + var queryable = this.Context.Queryable((t, t2, t3, t4, t5, T6, t7, t8, t9, t10, t11,t12) => new object[] { }).WithCacheIF(IsCache, CacheTime); + base.CopyQueryBuilder(queryable.QueryBuilder); + return queryable; + } public new ISugarQueryable AS(string tableName) { var entityName = typeof(AsT).Name; diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs index d5462a961..e49733137 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs @@ -97,8 +97,8 @@ namespace SqlSugar public IUpdateable IgnoreColumns(Expression> columns) { - var ignoreColumns = UpdateBuilder.GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => this.SqlBuilder.GetNoTranslationColumnName(it)).ToList(); - this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => !ignoreColumns.Contains(it.PropertyName)).ToList(); + var ignoreColumns = UpdateBuilder.GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => this.SqlBuilder.GetNoTranslationColumnName(it).ToLower()).ToList(); + this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => !ignoreColumns.Contains(it.PropertyName.ToLower())).ToList(); return this; } @@ -203,8 +203,33 @@ namespace SqlSugar this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => UpdateBuilder.SetValues.Any(v => SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase) || SqlBuilder.GetNoTranslationColumnName(v.Key).Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase)) || it.IsPrimarykey == true).ToList(); return this; } - [Obsolete("Use IUpdateable IgnoreColumns(bool ignoreAllNullColumns, bool isOffIdentity = false);")] + public IUpdateable UpdateColumnsIF(bool isUpdateColumns, Expression> columns) + { + if (isUpdateColumns) + UpdateColumns(columns); + return this; + } + public IUpdateable UpdateColumnsIF(bool isUpdateColumns, Expression> columns) + { + if (isUpdateColumns) + UpdateColumns(columns); + return this; + } + public IUpdateable UpdateColumnsIF(bool isUpdateColumns, Func updateColumMethod) + { + if (isUpdateColumns) + UpdateColumns(updateColumMethod); + return this; + } + public IUpdateable UpdateColumnsIF(bool isUpdateColumns, Expression> columns) + { + if (isUpdateColumns) + UpdateColumns(columns); + return this; + } + + [Obsolete("Use IUpdateable IgnoreColumns(bool ignoreAllNullColumns, bool isOffIdentity = false);")] public IUpdateable Where(bool isUpdateNull, bool IsOffIdentity = false) { UpdateBuilder.IsOffIdentity = IsOffIdentity; @@ -499,7 +524,7 @@ namespace SqlSugar } else if (versionColumn.PropertyInfo.PropertyType.IsIn(UtilConstants.ByteArrayType)) { - if (UtilMethods.GetLong((byte[])dbVersion)>UtilMethods.GetLong((byte[])currentVersion)) + if (UtilMethods.GetLong((byte[])dbVersion) > UtilMethods.GetLong((byte[])currentVersion)) { throw new VersionExceptions(string.Format("UpdateVersionValidation {0} Not the latest version ", versionColumn.PropertyName)); } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/CacheScheme/CacheKeyBuider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/CacheScheme/CacheKeyBuider.cs index ecbb293d0..4b6155ccc 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/CacheScheme/CacheKeyBuider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/CacheScheme/CacheKeyBuider.cs @@ -28,6 +28,7 @@ namespace SqlSugar result.IdentificationList.Add(queryBuilder.Take.ObjToString()); result.IdentificationList.Add(queryBuilder.Skip.ObjToString()); result.IdentificationList.Add(queryBuilder.IsCount.ObjToString()); + result.IdentificationList.Add(queryBuilder.GetSelectValue.ObjToString().Length.ObjToString()); if (queryBuilder.Parameters.HasValue()) { foreach (var item in queryBuilder.Parameters) diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/ConnectionConfig.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/ConnectionConfig.cs index b06cb99b4..2c25c7172 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/ConnectionConfig.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/ConnectionConfig.cs @@ -94,5 +94,6 @@ namespace SqlSugar public Action EntityService{ get; set; } + public Action EntityNameService { get; set; } } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/EntityInfo.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/EntityInfo.cs index 5e3830376..f3241b098 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/EntityInfo.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/EntityInfo.cs @@ -12,6 +12,7 @@ namespace SqlSugar private string _DbTableName; public string EntityName { get; set; } public string DbTableName { get { return _DbTableName == null ? EntityName : _DbTableName; } set { _DbTableName = value; } } + public string TableDescription { get; set; } public Type Type { get; set; } public List Columns { get; set; } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/Mapping/SugarMappingAttribute.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/Mapping/SugarMappingAttribute.cs index a44d15660..f281c3156 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/Mapping/SugarMappingAttribute.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/Mapping/SugarMappingAttribute.cs @@ -10,9 +10,15 @@ namespace SqlSugar public class SugarTable : Attribute { private SugarTable() { } public string TableName { get; set; } + public string TableDescription { get; set; } public SugarTable(string tableName) { this.TableName = tableName; } + public SugarTable(string tableName,string tableDescription) + { + this.TableName = tableName; + this.TableDescription = tableDescription; + } } [AttributeUsage(AttributeTargets.Property , Inherited = true)] public class SugarColumn : Attribute diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/ExpressionResult.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/ExpressionResult.cs index 228d2050b..316e71587 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/ExpressionResult.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/ExpressionResult.cs @@ -63,18 +63,29 @@ namespace SqlSugar { if (_Result == null) return null; if (IsUpper) - return _Result.ToString().ToUpper().TrimEnd(','); + return _Result.ToString().ToUpper().Replace(UtilConstants.ReplaceCommaKey,",").TrimEnd(','); else - return _Result.ToString().TrimEnd(','); + return _Result.ToString().Replace(UtilConstants.ReplaceCommaKey, ",").TrimEnd(','); } #region functions public string[] GetResultArray() { if (this._Result == null) return null; + var reslut = new List(); + if (IsUpper) - return this.Result.ToString().ToUpper().TrimEnd(',').Split(','); + reslut= this.Result.ToString().ToUpper().TrimEnd(',').Split(',').ToList(); else - return this.Result.ToString().TrimEnd(',').Split(','); + reslut= this.Result.ToString().TrimEnd(',').Split(',').ToList(); + + if (this.Result.ToString().Contains(UtilConstants.ReplaceCommaKey)) + { + for (int i = 0; i < reslut.Count; i++) + { + reslut[i] = reslut[i].Replace(UtilConstants.ReplaceCommaKey, ","); + } + } + return reslut.ToArray(); } public string GetResultString() @@ -82,12 +93,12 @@ namespace SqlSugar if (this._Result == null) return null; if (this._ResolveExpressType.IsIn(ResolveExpressType.SelectMultiple, ResolveExpressType.SelectSingle)) { - return this.Result.ToString().TrimEnd(','); + return this.Result.ToString().Replace(UtilConstants.ReplaceCommaKey, ",").TrimEnd(','); } if (IsUpper) - return this.Result.ToString().ToUpper(); + return this.Result.ToString().Replace(UtilConstants.ReplaceCommaKey, ",").ToUpper(); else - return this.Result.ToString(); + return this.Result.ToString().Replace(UtilConstants.ReplaceCommaKey, ","); } public void TrimEnd() diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/SugarParameter.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/SugarParameter.cs index 78e64abfe..a9e9484b4 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/SugarParameter.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/SugarParameter.cs @@ -91,6 +91,10 @@ namespace SqlSugar { this.DbType = System.Data.DbType.String; } + else if (type == UtilConstants.DateTimeOffsetType) + { + this.DbType = System.Data.DbType.DateTimeOffset; + } } public SugarParameter(string name, object value, bool isOutput) diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MemberInitExpressionResolve.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MemberInitExpressionResolve.cs index 048cca63b..26fbb5084 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MemberInitExpressionResolve.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MemberInitExpressionResolve.cs @@ -124,7 +124,7 @@ namespace SqlSugar { base.Expression = item; base.Start(); - parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameter.CommonTempData.ObjToString())); + parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameter.CommonTempData.ObjToString().Replace(",", UtilConstants.ReplaceCommaKey))); } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/NewArrayExpessionResolve.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/NewArrayExpessionResolve.cs index 086b84918..5d640113c 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/NewArrayExpessionResolve.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/NewArrayExpessionResolve.cs @@ -42,11 +42,11 @@ namespace SqlSugar { if (i > 0) { - base.Context.Result.Append("," + parameter.CommonTempData.ObjToString() + ","); + base.Context.Result.Append("," + parameter.CommonTempData.ObjToString().Replace(",",UtilConstants.ReplaceCommaKey) + ","); } else { - base.Context.Result.Append(parameter.CommonTempData.ObjToString() + ","); + base.Context.Result.Append(parameter.CommonTempData.ObjToString().Replace(",", UtilConstants.ReplaceCommaKey) + ","); } ++i; } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/ContextMethods.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/ContextMethods.cs index b6f7e7648..00e3ad276 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/ContextMethods.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/ContextMethods.cs @@ -269,6 +269,7 @@ namespace SqlSugar public SqlSugarClient CopyContext(bool isCopyEvents = false) { var newClient = new SqlSugarClient(this.TranslateCopy(Context.CurrentConnectionConfig)); + newClient.CurrentConnectionConfig.ConfigureExternalServices=Context.CurrentConnectionConfig.ConfigureExternalServices; newClient.MappingColumns = this.TranslateCopy(Context.MappingColumns); newClient.MappingTables = this.TranslateCopy(Context.MappingTables); newClient.IgnoreColumns = this.TranslateCopy(Context.IgnoreColumns); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/SqlSugarAccessory.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/SqlSugarAccessory.cs index f945fbdc2..cbc93ef7e 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/SqlSugarAccessory.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/SqlSugarAccessory.cs @@ -247,13 +247,14 @@ namespace SqlSugar #endregion #region Create Instance - protected ISugarQueryable CreateQueryable() where T : class, new() + protected ISugarQueryable CreateQueryable() { ISugarQueryable result = InstanceFactory.GetQueryable(this.CurrentConnectionConfig); return CreateQueryable(result); } - protected ISugarQueryable CreateQueryable(ISugarQueryable result) where T : class, new() + protected ISugarQueryable CreateQueryable(ISugarQueryable result) { + Check.Exception(typeof(T).IsClass()==false|| typeof(T).GetConstructors().Length==0, "Queryable<{0}> Error ,{0} is invalid , need is a class,and can new().", typeof(T).Name); var sqlBuilder = InstanceFactory.GetSqlbuilder(CurrentConnectionConfig); result.Context = this.Context; result.SqlBuilder = sqlBuilder; @@ -308,7 +309,7 @@ namespace SqlSugar return result; } - protected void CreateQueryJoin(Expression joinExpression, Type[] types, ISugarQueryable queryable) where T : class, new() + protected void CreateQueryJoin(Expression joinExpression, Type[] types, ISugarQueryable queryable) { this.CreateQueryable(queryable); string shortName = string.Empty; @@ -321,7 +322,7 @@ namespace SqlSugar queryable.SqlBuilder.QueryBuilder.Parameters.AddRange(paramters); } } - protected void CreateEasyQueryJoin(Expression joinExpression, Type[] types, ISugarQueryable queryable) where T : class, new() + protected void CreateEasyQueryJoin(Expression joinExpression, Type[] types, ISugarQueryable queryable) { this.CreateQueryable(queryable); string shortName = string.Empty; @@ -342,6 +343,7 @@ namespace SqlSugar expressionContext.Resolve(joinExpression, ResolveExpressType.Join); int i = 0; var joinArray = MergeJoinArray(expressionContext.Result.GetResultArray()); + if (joinArray == null) return null; parameters = expressionContext.Parameters; foreach (var entityType in entityTypeArray) { @@ -380,6 +382,7 @@ namespace SqlSugar List result = new List(); string joinValue = null; int i = 0; + if (joinArray == null) return null; foreach (var item in joinArray) { ++i; diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ICodeFirst.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ICodeFirst.cs index 374162329..015c360f3 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ICodeFirst.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ICodeFirst.cs @@ -8,6 +8,7 @@ namespace SqlSugar { SqlSugarClient Context { get; set; } ICodeFirst BackupTable(int maxBackupDataRows=int.MaxValue); + ICodeFirst SetStringDefaultLength(int length); void InitTables(string entitiesNamespace); void InitTables(string [] entitiesNamespaces); void InitTables(params Type [] entityTypes); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IDbMaintenance.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IDbMaintenance.cs index cb55982be..73ab5944a 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IDbMaintenance.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IDbMaintenance.cs @@ -37,6 +37,13 @@ namespace SqlSugar bool BackupTable(string oldTableName, string newTableName, int maxBackupDataRows = int.MaxValue); bool DropColumn(string tableName,string columnName); bool RenameColumn(string tableName, string oldColumnName, string newColumnName); + bool AddRemark(EntityInfo entity); + bool AddColumnRemark(string columnName,string tableName,string description); + bool DeleteColumnRemark(string columnName, string tableName); + bool IsAnyColumnRemark(string columnName, string tableName); + bool AddTableRemark( string tableName, string description); + bool DeleteTableRemark(string tableName); + bool IsAnyTableRemark(string tableName); #endregion } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IQueryable.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IQueryable.cs index bab64f28b..947ec2c91 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IQueryable.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IQueryable.cs @@ -14,7 +14,7 @@ namespace SqlSugar SqlSugarClient Context { get; set; } ISqlBuilder SqlBuilder { get; set; } QueryBuilder QueryBuilder { get; set; } - + ISugarQueryable Clone(); ISugarQueryable AS(string tableName); ISugarQueryable AS(string tableName); ISugarQueryable With(string withString); @@ -179,6 +179,7 @@ namespace SqlSugar #endregion #region Other + new ISugarQueryable Clone(); new ISugarQueryable AS(string tableName); new ISugarQueryable AS(string tableName); new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); @@ -246,6 +247,7 @@ namespace SqlSugar #endregion #region Other + new ISugarQueryable Clone(); new ISugarQueryable AS(string tableName); new ISugarQueryable AS(string tableName); new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); @@ -320,6 +322,7 @@ namespace SqlSugar #endregion #region Other + new ISugarQueryable Clone(); new ISugarQueryable AS(string tableName); new ISugarQueryable AS(string tableName); new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); @@ -396,6 +399,7 @@ namespace SqlSugar #endregion #region Other + new ISugarQueryable Clone(); new ISugarQueryable AS(string tableName); new ISugarQueryable AS(string tableName); new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); @@ -470,6 +474,7 @@ namespace SqlSugar #endregion #region Other + new ISugarQueryable Clone(); new ISugarQueryable AS(string tableName); new ISugarQueryable AS(string tableName); new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); @@ -549,6 +554,7 @@ namespace SqlSugar #endregion #region Other + new ISugarQueryable Clone(); new ISugarQueryable AS(string tableName); new ISugarQueryable AS(string tableName); new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); @@ -633,6 +639,7 @@ namespace SqlSugar #endregion #region Other + new ISugarQueryable Clone(); new ISugarQueryable AS(string tableName); new ISugarQueryable AS(string tableName); new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); @@ -724,6 +731,7 @@ namespace SqlSugar #endregion #region Other + new ISugarQueryable Clone(); new ISugarQueryable AS(string tableName); new ISugarQueryable AS(string tableName); new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); @@ -818,6 +826,7 @@ namespace SqlSugar #endregion #region Other + new ISugarQueryable Clone(); new ISugarQueryable AS(string tableName); new ISugarQueryable AS(string tableName); new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); @@ -917,6 +926,7 @@ namespace SqlSugar #endregion #region Other + new ISugarQueryable Clone(); new ISugarQueryable AS(string tableName); new ISugarQueryable AS(string tableName); new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); @@ -1021,6 +1031,7 @@ namespace SqlSugar #endregion #region Other + new ISugarQueryable Clone(); new ISugarQueryable AS(string tableName); new ISugarQueryable AS(string tableName); new ISugarQueryable Filter(string FilterName, bool isDisabledGobalFilter = false); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IUpdateable.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IUpdateable.cs index 21dee2c27..38fdc133a 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IUpdateable.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IUpdateable.cs @@ -38,6 +38,10 @@ namespace SqlSugar IUpdateable UpdateColumns(Expression> columns); IUpdateable UpdateColumns(Func updateColumMethod); IUpdateable UpdateColumns(Expression> columns); + IUpdateable UpdateColumnsIF(bool isUpdateColumns,Expression> columns); + IUpdateable UpdateColumnsIF(bool isUpdateColumns,Expression> columns); + IUpdateable UpdateColumnsIF(bool isUpdateColumns,Func updateColumMethod); + IUpdateable UpdateColumnsIF(bool isUpdateColumns,Expression> columns); IUpdateable IgnoreColumns(bool ignoreAllNullColumns, bool isOffIdentity = false); IUpdateable IgnoreColumns(Expression> columns); IUpdateable IgnoreColumns(Func ignoreColumMethod); 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 26df6cb10..64ebcba37 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/CodeFirst/MySqlCodeFirst.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/CodeFirst/MySqlCodeFirst.cs @@ -67,5 +67,10 @@ namespace SqlSugar if (item.IsPrimarykey) this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); } + + internal DbColumnInfo GetEntityColumnToDbColumn(EntityInfo entity, string dbTableName, EntityColumnInfo item) + { + return EntityColumnToDbColumn(entity,dbTableName,item); + } } } 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 99aee80a9..61405131e 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/DbMaintenance/MySqlDbMaintenance.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/MySql/DbMaintenance/MySqlDbMaintenance.cs @@ -176,9 +176,72 @@ namespace SqlSugar return "AUTO_INCREMENT"; } } + protected override string AddColumnRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string DeleteColumnRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string IsAnyColumnRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string AddTableRemarkSql + { + get + { + return "ALTER TABLE {0} COMMENT='{1}';"; + } + } + + protected override string DeleteTableRemarkSql + { + get + { + return "ALTER TABLE {0} COMMENT='';"; + } + } + + protected override string IsAnyTableRemarkSql + { + get + { + throw new NotSupportedException(); + } + } #endregion #region Methods + public override bool AddRemark(EntityInfo entity) + { + var db = this.Context; + db.DbMaintenance.AddTableRemark(entity.DbTableName, entity.TableDescription); + List columns = entity.Columns.Where(it => it.IsIgnore == false).ToList(); + foreach (var item in columns) + { + if (item.ColumnDescription != null) + { + var mySqlCodeFirst = this.Context.CodeFirst as MySqlCodeFirst; + string sql = GetUpdateColumnSql(entity.DbTableName, mySqlCodeFirst.GetEntityColumnToDbColumn(entity, entity.DbTableName, item)) + " " + (item.IsIdentity ? "AUTO_INCREMENT" : "") + " " + " COMMENT '" + item.ColumnDescription + "'"; + db.Ado.ExecuteCommand(sql); + } + } + return true; + } public override bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true) { if (columns.HasValue()) diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Oracle/DbMaintenance/OracleDbMaintenance.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Oracle/DbMaintenance/OracleDbMaintenance.cs index 9c1a5d9e6..78410a52d 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Oracle/DbMaintenance/OracleDbMaintenance.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Oracle/DbMaintenance/OracleDbMaintenance.cs @@ -169,6 +169,53 @@ namespace SqlSugar return "IDENTITY(1,1)"; } } + protected override string AddColumnRemarkSql + { + get + { + return "comment on column {1}.{0} is '{2}';"; + } + } + + protected override string DeleteColumnRemarkSql + { + get + { + return "comment on column {1}.{0} is '';"; + } + } + + protected override string IsAnyColumnRemarkSql + { + get + { + return "select * from user_col_comments where Table_Name='{1}' AND COLUMN_NAME='{0}' order by column_name"; + } + } + + protected override string AddTableRemarkSql + { + get + { + return "comment on table {0} is '{1}';"; + } + } + + protected override string DeleteTableRemarkSql + { + get + { + return "comment on table {0} is '';"; + } + } + + protected override string IsAnyTableRemarkSql + { + get + { + return "select * from user_tab_comments where Table_Name='{0}'order by Table_Name"; + } + } #endregion #region Methods diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/SqlServer/DbMaintenance/SqlServerDbMaintenance.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/SqlServer/DbMaintenance/SqlServerDbMaintenance.cs index ed59478f4..4996d6ca1 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/SqlServer/DbMaintenance/SqlServerDbMaintenance.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/SqlServer/DbMaintenance/SqlServerDbMaintenance.cs @@ -200,6 +200,70 @@ namespace SqlSugar return "IDENTITY(1,1)"; } } + + protected override string AddColumnRemarkSql + { + get + { + return "EXECUTE sp_addextendedproperty N'MS_Description', '{2}', N'user', N'dbo', N'table', N'{1}', N'column', N'{0}'"; ; + } + } + + protected override string DeleteColumnRemarkSql + { + get + { + return "EXEC sp_dropextendedproperty 'MS_Description','user',dbo,'table','{1}','column',{0}"; + } + + } + + protected override string IsAnyColumnRemarkSql + { + get + { + return @"SELECT" + + " A.name AS table_name," + + " B.name AS column_name," + + " C.value AS column_description" + + " FROM sys.tables A" + + " LEFT JOIN sys.extended_properties C ON C.major_id = A.object_id" + + " LEFT JOIN sys.columns B ON B.object_id = A.object_id AND C.minor_id = B.column_id" + + " INNER JOIN sys.schemas SC ON SC.schema_id = A.schema_id AND SC.name = 'dbo'"+ + " WHERE A.name = '{1}' and b.name = '{0}'"; + + } + } + + protected override string AddTableRemarkSql + { + get + { + return "EXECUTE sp_addextendedproperty N'MS_Description', '{1}', N'user', N'dbo', N'table', N'{0}', NULL, NULL"; + } + } + + protected override string DeleteTableRemarkSql + { + get + { + return "EXEC sp_dropextendedproperty 'MS_Description','user',dbo,'table','{0}' "; + } + + } + + protected override string IsAnyTableRemarkSql + { + get + { + return @"SELECT C.class_desc + FROM sys.tables A + LEFT JOIN sys.extended_properties C ON C.major_id = A.object_id + INNER JOIN sys.schemas SC ON SC.schema_id=A.schema_id AND SC.name='dbo' + WHERE A.name = '{0}' AND minor_id=0"; + } + + } #endregion public override bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true) diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Sqlite/DbMaintenance/SqliteDbMaintenance.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Sqlite/DbMaintenance/SqliteDbMaintenance.cs index 5eb077890..7884de213 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Sqlite/DbMaintenance/SqliteDbMaintenance.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/Sqlite/DbMaintenance/SqliteDbMaintenance.cs @@ -162,9 +162,60 @@ namespace SqlSugar return "AUTOINCREMENT"; } } + protected override string AddColumnRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string DeleteColumnRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string IsAnyColumnRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string AddTableRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string DeleteTableRemarkSql + { + get + { + throw new NotSupportedException(); + } + } + + protected override string IsAnyTableRemarkSql + { + get + { + throw new NotSupportedException(); + } + } #endregion #region Methods + public override bool AddRemark(EntityInfo entity) + { + return true; + } public override List GetColumnInfosByTableName(string tableName,bool isCache=true) { string cacheKey = "DbMaintenanceProvider.GetColumnInfosByTableName." + this.SqlBuilder.GetNoTranslationColumnName(tableName).ToLower(); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs index 9510d19b5..7b7693cc3 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs @@ -103,7 +103,7 @@ namespace SqlSugar /// /// Lambda Query operation /// - public virtual ISugarQueryable Queryable() where T : class, new() + public virtual ISugarQueryable Queryable() { InitMppingInfo(); @@ -113,7 +113,7 @@ namespace SqlSugar /// /// Lambda Query operation /// - public virtual ISugarQueryable Queryable(string shortName) where T : class, new() + public virtual ISugarQueryable Queryable(string shortName) { var queryable = Queryable(); queryable.SqlBuilder.QueryBuilder.TableShortName = shortName; @@ -129,7 +129,7 @@ namespace SqlSugar queryable.SqlBuilder.QueryBuilder.TableShortName = shortName; return queryable; } - public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + public virtual ISugarQueryable Queryable(Expression> joinExpression) { InitMppingInfo(); var types = new Type[] { typeof(T2) }; @@ -137,7 +137,7 @@ namespace SqlSugar this.CreateQueryJoin(joinExpression, types, queryable); return queryable; } - public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + public virtual ISugarQueryable Queryable(Expression> joinExpression) { InitMppingInfo(); var types = new Type[] { typeof(T2), typeof(T3) }; @@ -145,7 +145,7 @@ namespace SqlSugar this.CreateQueryJoin(joinExpression, types, queryable); return queryable; } - public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + public virtual ISugarQueryable Queryable(Expression> joinExpression) { InitMppingInfo(); var types = new Type[] { typeof(T2), typeof(T3), typeof(T4) }; @@ -153,7 +153,7 @@ namespace SqlSugar this.CreateQueryJoin(joinExpression, types, queryable); return queryable; } - public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + public virtual ISugarQueryable Queryable(Expression> joinExpression) { InitMppingInfo(); var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5) }; @@ -161,7 +161,7 @@ namespace SqlSugar this.CreateQueryJoin(joinExpression, types, queryable); return queryable; } - public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + public virtual ISugarQueryable Queryable(Expression> joinExpression) { InitMppingInfo(); var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6) }; @@ -169,7 +169,7 @@ namespace SqlSugar this.CreateQueryJoin(joinExpression, types, queryable); return queryable; } - public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + public virtual ISugarQueryable Queryable(Expression> joinExpression) { InitMppingInfo(); var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7) }; @@ -177,7 +177,7 @@ namespace SqlSugar this.CreateQueryJoin(joinExpression, types, queryable); return queryable; } - public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + public virtual ISugarQueryable Queryable(Expression> joinExpression) { InitMppingInfo(); var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8) }; @@ -186,7 +186,7 @@ namespace SqlSugar return queryable; } #region 9-12 - public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + public virtual ISugarQueryable Queryable(Expression> joinExpression) { InitMppingInfo(); var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9) }; @@ -194,7 +194,7 @@ namespace SqlSugar this.CreateQueryJoin(joinExpression, types, queryable); return queryable; } - public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + public virtual ISugarQueryable Queryable(Expression> joinExpression) { InitMppingInfo(); var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10) }; @@ -202,7 +202,7 @@ namespace SqlSugar this.CreateQueryJoin(joinExpression, types, queryable); return queryable; } - public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + public virtual ISugarQueryable Queryable(Expression> joinExpression) { InitMppingInfo(); var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11) }; @@ -210,7 +210,7 @@ namespace SqlSugar this.CreateQueryJoin(joinExpression, types, queryable); return queryable; } - public virtual ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() + public virtual ISugarQueryable Queryable(Expression> joinExpression) { InitMppingInfo(); var types = new Type[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12) }; @@ -350,7 +350,7 @@ namespace SqlSugar var shortName1 = joinExpression.Parameters[0].Name; var sqlObj1 = joinQueryable1.ToSql(); string sql1 = sqlObj1.Key; - UtilMethods.RepairReplicationParameters(ref sql1, sqlObj1.Value.ToArray(), 0); + UtilMethods.RepairReplicationParameters(ref sql1, sqlObj1.Value.ToArray(), 0,"Join"); queryable.QueryBuilder.EntityName = sqlBuilder.GetPackTable(sql1, shortName1); ; queryable.QueryBuilder.Parameters.AddRange(sqlObj1.Value); @@ -358,7 +358,7 @@ namespace SqlSugar var shortName2 = joinExpression.Parameters[1].Name; var sqlObj2 = joinQueryable2.ToSql(); string sql2 = sqlObj2.Key; - UtilMethods.RepairReplicationParameters(ref sql2, sqlObj2.Value.ToArray(), 1); + UtilMethods.RepairReplicationParameters(ref sql2, sqlObj2.Value.ToArray(), 1, "Join"); queryable.QueryBuilder.Parameters.AddRange(sqlObj2.Value); var exp = queryable.QueryBuilder.GetExpressionValue(joinExpression, ResolveExpressType.WhereMultiple); queryable.QueryBuilder.JoinQueryInfos.Add(new JoinQueryInfo() { JoinIndex = 0, JoinType = joinType, JoinWhere = exp.GetResultString(), TableName = sqlBuilder.GetPackTable(sql2, shortName2) }); @@ -377,7 +377,7 @@ namespace SqlSugar { var sqlObj = item.ToSql(); string sql = sqlObj.Key; - UtilMethods.RepairReplicationParameters(ref sql, sqlObj.Value.ToArray(), i); + UtilMethods.RepairReplicationParameters(ref sql, sqlObj.Value.ToArray(), i, "UnionAll"); if (sqlObj.Value.HasValue()) allItems.Add(new KeyValuePair>(sql, sqlObj.Value)); else @@ -405,7 +405,7 @@ namespace SqlSugar { var sqlObj = item.ToSql(); string sql = sqlObj.Key; - UtilMethods.RepairReplicationParameters(ref sql, sqlObj.Value.ToArray(), i); + UtilMethods.RepairReplicationParameters(ref sql, sqlObj.Value.ToArray(), i, "Union"); if (sqlObj.Value.HasValue()) allItems.Add(new KeyValuePair>(sql, sqlObj.Value)); else diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilConstants.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilConstants.cs index f798701c8..0119b2a9d 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilConstants.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilConstants.cs @@ -13,6 +13,7 @@ namespace SqlSugar internal const char SpaceChar =' '; internal const string AssemblyName = "SqlSugar"; internal const string ReplaceKey = "{662E689B-17A1-4D06-9D27-F29EAB8BC3D6}"; + internal const string ReplaceCommaKey = "{112A689B-17A1-4A06-9D27-A39EAB8BC3D5}"; internal static Type IntType = typeof(int); internal static Type LongType = typeof(long); @@ -26,6 +27,7 @@ namespace SqlSugar internal static Type DecType = typeof(decimal); internal static Type StringType = typeof(string); internal static Type DateType = typeof(DateTime); + internal static Type DateTimeOffsetType = typeof(DateTimeOffset); internal static Type ByteArrayType = typeof(byte[]); internal static Type ModelType= typeof(ModelContext); internal static Type DynamicType = typeof(ExpandoObject); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilMethods.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilMethods.cs index 821b2b45d..945aaf8c3 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilMethods.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilMethods.cs @@ -68,7 +68,7 @@ namespace SqlSugar return (T)Convert.ChangeType(obj, typeof(T)); } - internal static void RepairReplicationParameters(ref string appendSql, SugarParameter[] parameters, int addIndex) + internal static void RepairReplicationParameters(ref string appendSql, SugarParameter[] parameters, int addIndex,string append=null) { if (appendSql.HasValue() && parameters.HasValue()) { @@ -76,7 +76,7 @@ namespace SqlSugar { //Compatible with.NET CORE parameters case var name = parameter.ParameterName; - string newName = name + addIndex; + string newName = name +append+ addIndex; appendSql = appendSql.Replace(name, newName); parameter.ParameterName = newName; } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqliteTest/DataBase/SqlSugar4xTest.sqlite b/Src/Asp.NetCore2/SqlSeverTest/SqliteTest/DataBase/SqlSugar4xTest.sqlite index 830dd8ddf85c3ee075875991445aac58253c4166..bbbc7417e436e79ba85ba9ce0c28621101449591 100644 GIT binary patch literal 327680 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