diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DeleteProvider/DeleteableProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DeleteProvider/DeleteableProvider.cs index c8944dd76..374d1e918 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DeleteProvider/DeleteableProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DeleteProvider/DeleteableProvider.cs @@ -220,6 +220,15 @@ namespace SqlSugar return this; } + public IDeleteable WhereColumns(Expression> columns) + { + if (columns != null) + { + tempPrimaryKeys = DeleteBuilder.GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => this.SqlBuilder.GetNoTranslationColumnName(it)).ToList(); + } + return this; + } + public IDeleteable RemoveDataCache() { this.RemoveCacheFunc = () => @@ -445,7 +454,7 @@ namespace SqlSugar DiffLogColumnInfo addItem = new DiffLogColumnInfo(); addItem.Value = row[col.ColumnName]; addItem.ColumnName = col.ColumnName; - addItem.ColumnDescription = this.EntityInfo.Columns.First(it => it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase)).ColumnDescription; + addItem.ColumnDescription = this.EntityInfo.Columns.Where(it=>it.DbColumnName!=null).First(it => it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase)).ColumnDescription; item.Columns.Add(addItem); } result.Add(item); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/InsertableProvider/InsertableProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/InsertableProvider/InsertableProvider.cs index 92b5e682a..9c2dabb57 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/InsertableProvider/InsertableProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/InsertableProvider/InsertableProvider.cs @@ -475,7 +475,7 @@ namespace SqlSugar { columnInfo.IsArray = true; } - if (columnInfo.PropertyType.IsEnum()) + if (columnInfo.PropertyType.IsEnum()&& columnInfo.Value!=null) { columnInfo.Value = Convert.ToInt64(columnInfo.Value); } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs index 5bbd8f352..b0f3fd34e 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs @@ -197,6 +197,70 @@ namespace SqlSugar { return WhereClass(new List() { whereClass }, ignoreDefaultValue); } + public ISugarQueryable WhereClassByPrimaryKey(List list) + { + _WhereClassByPrimaryKey(list); + return this; + } + public ISugarQueryable WhereClassByPrimaryKey(T data) + { + _WhereClassByPrimaryKey(new List() { data }); + return this; + } + + /// + /// if a property that is primary key is a condition + /// + /// + /// + public ISugarQueryable _WhereClassByPrimaryKey(List whereClassTypes) + { + + if (whereClassTypes.HasValue()) + { + var columns = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsIgnore == false && it.IsPrimarykey == true).ToList(); + Check.Exception(columns == null || columns.Count == 0, "{0} no primary key, Can not use WhereClassByPrimaryKey ", typeof(T).Name); + Check.Exception(this.QueryBuilder.IsSingle() == false, "No support join query"); + List whereModels = new List(); + foreach (var item in whereClassTypes) + { + var cons = new ConditionalCollections(); + foreach (var column in columns) + { + WhereType WhereType = WhereType.And; + var value = column.PropertyInfo.GetValue(item, null); + if (cons.ConditionalList == null) + { + cons.ConditionalList = new List>(); + if (QueryBuilder.WhereInfos.IsNullOrEmpty() && whereModels.IsNullOrEmpty()) + { + + } + else + { + WhereType = WhereType.Or; + } + } + cons.ConditionalList.Add(new KeyValuePair(WhereType, new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + FieldName = this.QueryBuilder.Builder.GetTranslationColumnName(column.DbColumnName), + FieldValue = value.ObjToString() + })); + } + if (cons.HasValue()) + { + whereModels.Add(cons); + } + } + this.Where(whereModels); + } + else + { + this.Where(" 1=2 "); + } + return this; + } /// /// if a property that is not empty is a condition /// @@ -616,7 +680,10 @@ namespace SqlSugar Check.Exception(this.QueryBuilder.SelectValue.IsNullOrEmpty(), "MergeTable need to use Queryable.Select Method ."); Check.Exception(this.QueryBuilder.Skip > 0 || this.QueryBuilder.Take > 0 || this.QueryBuilder.OrderByValue.HasValue(), "MergeTable Queryable cannot Take Skip OrderBy PageToList "); var sqlobj = this.ToSql(); - return this.Context.Queryable().AS(SqlBuilder.GetPackTable(sqlobj.Key, "MergeTable")).AddParameters(sqlobj.Value).Select("*").With(SqlWith.Null); + var index = QueryBuilder.WhereIndex+1; + var result= this.Context.Queryable().AS(SqlBuilder.GetPackTable(sqlobj.Key, "MergeTable")).AddParameters(sqlobj.Value).Select("*").With(SqlWith.Null); + result.QueryBuilder.WhereIndex = index; + return result; } public ISugarQueryable Distinct() diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SaveableProvider/Storageable.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SaveableProvider/Storageable.cs new file mode 100644 index 000000000..415203ed9 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SaveableProvider/Storageable.cs @@ -0,0 +1,209 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public class Storageable : IStorageable where T : class, new() + { + SqlSugarProvider Context { get; set; } + internal ISqlBuilder Builder; + List Parameters; + List> allDatas = new List>(); + List dbDataList = new List(); + List, bool>, string>> whereFuncs = new List, bool>, string>>(); + Expression> whereExpression; + public Storageable(List datas, SqlSugarProvider context) + { + this.Context = context; + if (datas == null) + datas = new List(); + this.allDatas = datas.Select(it => new StorageableInfo() + { + Item = it + }).ToList(); + } + + public IStorageable SplitInsert(Func, bool> conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, bool>, string>(StorageType.Insert, conditions, message)); + return this; + } + public IStorageable SplitDelete(Func, bool> conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, bool>, string>(StorageType.Delete, conditions, message)); + return this; + } + public IStorageable SplitUpdate(Func, bool> conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, bool>, string>(StorageType.Update, conditions, message)); + return this; + } + public IStorageable SplitError(Func, bool> conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, bool>, string>(StorageType.Error, conditions, message)); + return this; + } + + public IStorageable SplitIgnore(Func, bool> conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, bool>, string>(StorageType.Ignore, conditions, message)); + return this; + } + + public IStorageable SplitOther(Func, bool> conditions, string message = null) + { + whereFuncs.Add(new KeyValuePair, bool>, string>(StorageType.Other, conditions, message)); + return this; + } + + public StorageableResult ToStorage() + { + if (this.allDatas.Count == 0) + return new StorageableResult(); + var pkInfos = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsPrimarykey); + if (whereExpression==null&&!pkInfos.Any()) + { + Check.Exception(true, "Need primary key or WhereColumn"); + } + if (whereExpression == null && pkInfos.Any()) + { + this.Context.Utilities.PageEach(allDatas, 300, item => { + var addItems=this.Context.Queryable().WhereClassByPrimaryKey(item.Select(it => it.Item).ToList()).ToList(); + dbDataList.AddRange(addItems); + }); + } + var messageList = allDatas.Select(it => new StorageableMessage() + { + Item = it.Item, + Database = dbDataList + }).ToList(); + foreach (var item in whereFuncs.OrderByDescending(it => (int)it.key)) + { + List> whereList = messageList.Where(it => it.StorageType == null).ToList(); + Func, bool> exp = item.value1; + var list = whereList.Where(exp).ToList(); + foreach (var it in list) + { + it.StorageType = item.key; + it.StorageMessage = item.value2; + } + } + var delete = messageList.Where(it => it.StorageType == StorageType.Delete).ToList(); + var update = messageList.Where(it => it.StorageType == StorageType.Update).ToList(); + var inset = messageList.Where(it => it.StorageType == StorageType.Insert).ToList(); + var error = messageList.Where(it => it.StorageType == StorageType.Error).ToList(); + var ignore = messageList.Where(it => it.StorageType == StorageType.Ignore || it.StorageType == null).ToList(); + var other = messageList.Where(it => it.StorageType == StorageType.Other).ToList(); + StorageableResult result = new StorageableResult() + { + AsDeleteable = this.Context.Deleteable(), + AsUpdateable = this.Context.Updateable(update.Select(it => it.Item).ToList()), + AsInsertable = this.Context.Insertable(inset.Select(it => it.Item).ToList()), + OtherList = other, + InsertList = inset, + DeleteList = delete, + UpdateList = update, + ErrorList = error, + IgnoreList = ignore, + TotalList = messageList + }; + if (this.whereExpression != null) + { + result.AsUpdateable.WhereColumns(whereExpression); + result.AsDeleteable.WhereColumns(whereExpression); + } + result.AsDeleteable.Where(delete.Select(it => it.Item).ToList()); + return result; + } + + public IStorageable WhereColumns(Expression> columns) + { + if (columns == null) + return this; + else + { + List list = GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => Builder.GetNoTranslationColumnName(it)).ToList(); + var dbColumns = this.Context.EntityMaintenance.GetEntityInfo().Columns.Where(it => it.IsIgnore == false); + var whereColumns = dbColumns.Where(it => list.Any(y => + it.DbColumnName.Equals(y, StringComparison.CurrentCultureIgnoreCase) || + it.PropertyName.Equals(y, StringComparison.CurrentCultureIgnoreCase)) + ).ToList(); + if (whereColumns.Count == 0) + { + whereColumns = dbColumns.Where(it => it.IsPrimarykey).ToList(); + } + if (whereColumns.Count > 0) + { + this.Context.Utilities.PageEach(allDatas, 200, itemList => + { + List conditList = new List(); + SetConditList(itemList, whereColumns, conditList); + var addItem = this.Context.Queryable().Where(conditList).ToList(); + this.dbDataList.AddRange(addItem); + }); + } + this.whereExpression = columns; + return this; + } + } + + private static void SetConditList(List> itemList, List whereColumns, List conditList) + { + ; + foreach (var dataItem in itemList) + { + var condition = new ConditionalCollections() + { + ConditionalList = new List>() + }; + conditList.Add(condition); + int i = 0; + foreach (var item in whereColumns) + { + condition.ConditionalList.Add(new KeyValuePair(i==0?WhereType.Or :WhereType.And, new ConditionalModel() + { + FieldName = item.DbColumnName, + ConditionalType = ConditionalType.Equal, + FieldValue = item.PropertyInfo.GetValue(dataItem.Item, null) + "" + })); + ++i; + } + } + } + + public virtual ExpressionResult GetExpressionValue(Expression expression, ResolveExpressType resolveType) + { + ILambdaExpressions resolveExpress = InstanceFactory.GetLambdaExpressions(this.Context.CurrentConnectionConfig); ; + if (this.Context.CurrentConnectionConfig.MoreSettings != null) + { + resolveExpress.PgSqlIsAutoToLower = this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower; + } + else + { + resolveExpress.PgSqlIsAutoToLower = true; + } + resolveExpress.MappingColumns = Context.MappingColumns; + resolveExpress.MappingTables = Context.MappingTables; + resolveExpress.IgnoreComumnList = Context.IgnoreColumns; + resolveExpress.SqlFuncServices = Context.CurrentConnectionConfig.ConfigureExternalServices == null ? null : Context.CurrentConnectionConfig.ConfigureExternalServices.SqlFuncServices; + resolveExpress.InitMappingInfo = Context.InitMappingInfo; + resolveExpress.RefreshMapping = () => + { + resolveExpress.MappingColumns = Context.MappingColumns; + resolveExpress.MappingTables = Context.MappingTables; + resolveExpress.IgnoreComumnList = Context.IgnoreColumns; + resolveExpress.SqlFuncServices = Context.CurrentConnectionConfig.ConfigureExternalServices == null ? null : Context.CurrentConnectionConfig.ConfigureExternalServices.SqlFuncServices; + }; + resolveExpress.Resolve(expression, resolveType); + if (this.Parameters == null) + this.Parameters = new List(); + this.Parameters.AddRange(resolveExpress.Parameters); + var result = resolveExpress.Result; + return result; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs index 6757cbf97..eb601cdad 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs @@ -4,6 +4,7 @@ using System.Data.SqlClient; using System.Dynamic; using System.Linq; using System.Linq.Expressions; +using System.Reflection; using System.Text; using System.Text.RegularExpressions; @@ -294,7 +295,15 @@ namespace SqlSugar if (!IsDisabledGobalFilter && this.Context.QueryFilter.GeFilterList.HasValue()) { var gobalFilterList = this.Context.QueryFilter.GeFilterList.Where(it => it.FilterName.IsNullOrEmpty()).ToList(); - foreach (var item in gobalFilterList.Where(it => it.IsJoinQuery == !IsSingle())) + + foreach (var item in gobalFilterList) + { + if (item.GetType().Name.StartsWith("TableFilterItem")) + { + AppendTableFilter(item); + } + } + foreach (var item in gobalFilterList.Where(it=>it.GetType().Name=="SqlFilterItem").Where(it => it.IsJoinQuery == !IsSingle())) { var filterResult = item.FilterValue(this.Context); WhereInfos.Add(this.Builder.AppendWhereOrAnd(this.WhereInfos.IsNullOrEmpty(), filterResult.Sql + UtilConstants.Space)); @@ -307,6 +316,67 @@ namespace SqlSugar } } + private void AppendTableFilter(SqlFilterItem item) + { + BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic; + Type type = item.GetType(); + PropertyInfo field = type.GetProperty("exp", flag); + Type ChildType = type.GetProperty("type", flag).GetValue(item,null) as Type; + var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(ChildType); + var exp=field.GetValue(item,null) as Expression; + var isMain = ChildType == this.EntityType; + var isSingle = IsSingle(); + var expValue = GetExpressionValue(exp, isSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple); + var sql = expValue.GetResultString(); + var itName = (exp as LambdaExpression).Parameters[0].Name; + itName = this.Builder.GetTranslationColumnName(itName) + "."; + var isEasyJoin = this.EasyJoinInfos.Count > 0; + if (WhereInfos.Count == 0) + { + sql =( " WHERE " + sql); + }else + { + sql = (" AND " + sql); + } + if (isSingle) + { + if (ChildType != this.EntityType) + { + return; + } + } + else if (isMain) + { + var shortName = this.Builder.GetTranslationColumnName(TableShortName) + "."; + sql = sql.Replace(itName, shortName); + } + else if (isEasyJoin) + { + var easyInfo = EasyJoinInfos.FirstOrDefault(it => + it.Value.Equals(entityInfo.DbTableName, StringComparison.CurrentCultureIgnoreCase) || + it.Value.Equals(entityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase)); + if (easyInfo.Key==null) + { + return; + } + var shortName = this.Builder.GetTranslationColumnName(easyInfo.Key.Trim()) + "."; + sql = sql.Replace(itName, shortName); + } + else + { + var easyInfo = JoinQueryInfos.FirstOrDefault(it => + it.TableName.Equals(entityInfo.DbTableName, StringComparison.CurrentCultureIgnoreCase) || + it.TableName.Equals(entityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase)); + if (easyInfo == null) + { + return; + } + var shortName = this.Builder.GetTranslationColumnName(easyInfo.ShortName.Trim()) + "."; + sql = sql.Replace(itName, shortName); + } + WhereInfos.Add(sql); + } + public virtual string GetExternalOrderBy(string externalOrderBy) { return Regex.Replace(externalOrderBy, @"\[\w+\]\.", ""); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SugarProvider/SqlSugarProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SugarProvider/SqlSugarProvider.cs index de592afba..e2e53c483 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SugarProvider/SqlSugarProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SugarProvider/SqlSugarProvider.cs @@ -674,7 +674,11 @@ namespace SqlSugar } public virtual IUpdateable Updateable(List UpdateObjs) where T : class, new() { - Check.ArgumentNullException(UpdateObjs, "Updateable.UpdateObjs can't be null"); + //Check.ArgumentNullException(UpdateObjs, "Updateable.UpdateObjs can't be null"); + if (UpdateObjs == null) + { + UpdateObjs = new List(); + } return Updateable(UpdateObjs.ToArray()); } public virtual IUpdateable Updateable(T UpdateObj) where T : class, new() @@ -735,6 +739,14 @@ namespace SqlSugar { return new SaveableProvider(this, saveObject); } + public IStorageable Storageable(List dataList) where T : class, new() + { + this.InitMappingInfo(); + var sqlBuilder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig); + var result= new Storageable(dataList,this); + result.Builder = sqlBuilder; + return result; + } #endregion #region DbFirst diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs index 247c292d5..c611c7c21 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs @@ -53,6 +53,10 @@ namespace SqlSugar public virtual int ExecuteCommand() { string sql = _ExecuteCommand(); + if (string.IsNullOrEmpty(sql)) + { + return 0; + } var result = this.Ado.ExecuteCommand(sql, UpdateBuilder.Parameters == null ? null : UpdateBuilder.Parameters.ToArray()); After(sql); return result; @@ -64,6 +68,10 @@ namespace SqlSugar public async Task ExecuteCommandAsync() { string sql = _ExecuteCommand(); + if (string.IsNullOrEmpty(sql)) + { + return 0; + } var result = await this.Ado.ExecuteCommandAsync(sql, UpdateBuilder.Parameters == null ? null : UpdateBuilder.Parameters.ToArray()); After(sql); return result; @@ -360,7 +368,7 @@ namespace SqlSugar this.UpdateBuilder.TableName = mappingInfo.DbTableName; } } - Check.Exception(UpdateObjs == null || UpdateObjs.Count() == 0, "UpdateObjs is null"); + //Check.Exception(UpdateObjs == null || UpdateObjs.Count() == 0, "UpdateObjs is null"); int i = 0; foreach (var item in UpdateObjs) { @@ -425,7 +433,7 @@ namespace SqlSugar PropertyType = UtilMethods.GetUnderType(column.PropertyInfo), TableId = i }; - if (columnInfo.PropertyType.IsEnum()) + if (columnInfo.PropertyType.IsEnum()&& columnInfo.Value!=null) { columnInfo.Value = Convert.ToInt64(columnInfo.Value); } @@ -451,11 +459,16 @@ namespace SqlSugar private void PreToSql() { + UpdateBuilder.PrimaryKeys = GetPrimaryKeys(); if (this.IsWhereColumns) { foreach (var pkName in UpdateBuilder.PrimaryKeys) { + if (WhereColumnList != null&& WhereColumnList.Count()>0) + { + continue; + } var isContains = this.UpdateBuilder.DbColumnInfoList.Select(it => it.DbColumnName.ToLower()).Contains(pkName.ToLower()); Check.Exception(isContains == false, "Use UpdateColumns().WhereColumn() ,UpdateColumns need {0}", pkName); } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/SqlFilter.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/SqlFilter.cs index d650ac145..0cc906be9 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/SqlFilter.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Entities/SqlFilter.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using System.Text; namespace SqlSugar @@ -18,6 +19,25 @@ namespace SqlSugar public bool IsJoinQuery { get; set; } } + public class TableFilterItem: SqlFilterItem where T :class,new() + { + private TableFilterItem() + { + + } + private Expression exp { get; set; } + private Type type { get; set; } + public TableFilterItem(Expression> expression) + { + exp = expression; + type = typeof(T); + } + private new string FilterName { get; set; } + private new Func FilterValue { get; set; } + private new bool IsJoinQuery { get; set; } + } + + public class SqlFilterResult { public string Sql { get; set; } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/BinaryExpressionResolve.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/BinaryExpressionResolve.cs index a503bb001..e8634d07e 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/BinaryExpressionResolve.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/BinaryExpressionResolve.cs @@ -8,6 +8,21 @@ namespace SqlSugar public class BinaryExpressionResolve : BaseResolve { public BinaryExpressionResolve(ExpressionParameter parameter) : base(parameter) + { + switch (parameter.Context.ResolveType) + { + case ResolveExpressType.FieldSingle: + case ResolveExpressType.FieldMultiple: + var sql = base.GetNewExpressionValue(this.Expression); + this.Context.Result.Append(sql); + break; + default: + Other(parameter); + break; + } + } + + private void Other(ExpressionParameter parameter) { var expression = this.Expression as BinaryExpression; var operatorValue = parameter.OperatorValue = ExpressionTool.GetOperator(expression.NodeType); @@ -32,15 +47,15 @@ namespace SqlSugar { base.Context.Result.Replace(ExpressionConst.FormatSymbol, ExpressionConst.LeftParenthesis + ExpressionConst.FormatSymbol); } - if (leftExpression is UnaryExpression && (leftExpression as UnaryExpression).Operand is UnaryExpression&& (leftExpression as UnaryExpression).NodeType == ExpressionType.Convert) + if (leftExpression is UnaryExpression && (leftExpression as UnaryExpression).Operand is UnaryExpression && (leftExpression as UnaryExpression).NodeType == ExpressionType.Convert) { leftExpression = (leftExpression as UnaryExpression).Operand; } - if (leftExpression is UnaryExpression && (leftExpression as UnaryExpression).Operand.Type == UtilConstants.BoolType && (leftExpression as UnaryExpression).NodeType == ExpressionType.Convert&&rightExpression.Type==UtilConstants.BoolTypeNull) + if (leftExpression is UnaryExpression && (leftExpression as UnaryExpression).Operand.Type == UtilConstants.BoolType && (leftExpression as UnaryExpression).NodeType == ExpressionType.Convert && rightExpression.Type == UtilConstants.BoolTypeNull) { leftExpression = (leftExpression as UnaryExpression).Operand; } - if (rightExpression is UnaryExpression&& (rightExpression as UnaryExpression).Operand.Type==UtilConstants.BoolType&& (rightExpression as UnaryExpression).NodeType == ExpressionType.Convert) + if (rightExpression is UnaryExpression && (rightExpression as UnaryExpression).Operand.Type == UtilConstants.BoolType && (rightExpression as UnaryExpression).NodeType == ExpressionType.Convert) { rightExpression = (rightExpression as UnaryExpression).Operand; } @@ -49,7 +64,7 @@ namespace SqlSugar base.Expression = leftExpression; base.IsLeft = true; base.Start(); - if (leftExpression is UnaryExpression && leftExpression.Type == UtilConstants.BoolType&&!this.Context.Result.Contains(ExpressionConst.ExpressionReplace)) + if (leftExpression is UnaryExpression && leftExpression.Type == UtilConstants.BoolType && !this.Context.Result.Contains(ExpressionConst.ExpressionReplace)) { this.Context.Result.AppendFormat(" {0} ", ExpressionTool.GetOperator(expression.NodeType)); } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MapperExpressionResolve.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MapperExpressionResolve.cs index 8a1548d95..9487fb7b9 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MapperExpressionResolve.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MapperExpressionResolve.cs @@ -45,7 +45,7 @@ namespace SqlSugar //var SelectInfo = GetSelectInfo(expression); this.context.InitMappingInfo(childExpression.Expression.Type); var entity = this.context.EntityMaintenance.GetEntityInfo(childExpression.Expression.Type); - oneToMany(callName, entity, childExpression.Expression.ToString(), fillInfo, mappingFild1Info, mappingFild1Info2); + oneToMany(methodExpression, callName, entity, childExpression.Expression.ToString(), fillInfo, mappingFild1Info, mappingFild1Info2); } private void ResolveMember() @@ -99,33 +99,60 @@ namespace SqlSugar .Select(sqlBuilder.GetTranslationColumnName(selectInfo.FieldName)).ToSql().Key; } - private void oneToMany(string methodName,EntityInfo mainEntity,string shortName,MapperExpressionInfo fillInfo, MapperExpressionInfo mappingFild1Info, MapperExpressionInfo mappingFild1Info2) + private void oneToMany(MethodCallExpression methodCallExpression,string methodName,EntityInfo mainEntity,string shortName,MapperExpressionInfo fillInfo, MapperExpressionInfo mappingFild1Info, MapperExpressionInfo mappingFild1Info2) { - var pkColumn = mainEntity.Columns.FirstOrDefault(it=>it.IsPrimarykey==true); + var pkColumn = mainEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); if (pkColumn == null) { pkColumn = mainEntity.Columns.FirstOrDefault(); } var tableName = sqlBuilder.GetTranslationTableName(fillInfo.EntityInfo.DbTableName); var whereLeft = sqlBuilder.GetTranslationColumnName(mappingFild1Info.FieldString); - var whereRight = sqlBuilder.GetTranslationColumnName(shortName+"."+pkColumn.DbColumnName); - + var whereRight = sqlBuilder.GetTranslationColumnName(shortName + "." + pkColumn.DbColumnName); + string whereExpression = GetWhereExpression(methodCallExpression); if (methodName == "Any") { - this.sql = " ("+this.context.Queryable() + this.sql = " (" + this.context.Queryable() .AS(tableName) .Where(string.Format(" {0}={1} ", whereLeft, whereRight)) - .Select("COUNT(1)").ToSql().Key+")>0 "; + .WhereIF(!string.IsNullOrEmpty(whereExpression), whereExpression) + .Select("COUNT(1)").ToSql().Key + ")>0 "; } else { this.sql = this.context.Queryable() .AS(tableName) .Where(string.Format(" {0}={1} ", whereLeft, whereRight)) + .WhereIF(!string.IsNullOrEmpty(whereExpression), whereExpression) .Select("COUNT(1)").ToSql().Key; } } + private string GetWhereExpression(MethodCallExpression methodCallExpression) + { + if (methodCallExpression.Arguments.Count <= 1) + return null; + var exp= methodCallExpression.Arguments[1]; + var querybuiler=InstanceFactory.GetQueryBuilder(this.context.CurrentConnectionConfig); + querybuiler.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.context.CurrentConnectionConfig); + querybuiler.Builder = InstanceFactory.GetSqlbuilder(this.context.CurrentConnectionConfig); + querybuiler.Builder.Context = querybuiler.Context; + querybuiler.Builder.QueryBuilder = querybuiler; + querybuiler.Context = this.context; + var expValue=querybuiler.GetExpressionValue(exp, ResolveExpressType.WhereMultiple); + var paramterName = (exp as LambdaExpression).Parameters[0].Name; + var sql = expValue.GetResultString(); + sql = sql.Replace(querybuiler.Builder.GetTranslationColumnName(paramterName) + ".", ""); + if (querybuiler.Parameters != null && querybuiler.Parameters.Count > 0) + { + foreach (var item in querybuiler.Parameters) + { + sql = sql.Replace(item.ParameterName,item.Value.ObjToString().ToSqlValue()); + } + } + return sql; + } + private MapperExpressionInfo GetSelectInfo(Expression expression) { diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/ContextMethods.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/ContextMethods.cs index e37e81435..4680f5d1e 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/ContextMethods.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/ContextMethods.cs @@ -572,6 +572,29 @@ namespace SqlSugar return table.Rows.Cast().ToDictionary(x => x[0].ToString(), x => x[1]); } + public List> DataTableToDictionaryList(DataTable dt) + { + List> result = new List>(); + if (dt != null && dt.Rows.Count > 0) + { + foreach (DataRow dr in dt.Rows) + { + Dictionary dic = new Dictionary(); + for (int i = 0; i < dr.Table.Columns.Count; i++) + { + var value = dr[dr.Table.Columns[i].ColumnName]; + if (value == DBNull.Value) + { + value = null; + } + dic.Add(dr.Table.Columns[i].ColumnName.ToString(), value); + } + result.Add(dic); + } + } + return result; + } + #endregion #region Cache diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IContextMethods.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IContextMethods.cs index 2bb6e6a1d..dff5adbf4 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IContextMethods.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IContextMethods.cs @@ -29,6 +29,7 @@ namespace SqlSugar List DataTableToList(DataTable table); DataTable ListToDataTable(List list); Dictionary DataTableToDictionary(DataTable table); + List> DataTableToDictionaryList(DataTable table); ICacheService GetReflectionInoCacheInstance(); void RemoveCacheAll(); void RemoveCacheAll(); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IDeleteable.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IDeleteable.cs index b292d6db8..e50a40e44 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IDeleteable.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IDeleteable.cs @@ -29,6 +29,7 @@ namespace SqlSugar IDeleteable Where(string whereString, SugarParameter parameter); IDeleteable Where(string whereString, SugarParameter[] parameters); IDeleteable Where(string whereString, List parameters); + IDeleteable WhereColumns(Expression> columns); IDeleteable EnableDiffLogEvent(object businessData = null); IDeleteable RemoveDataCache(); KeyValuePair> ToSql(); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IQueryable.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IQueryable.cs index e522f4dcb..5340e228b 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IQueryable.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IQueryable.cs @@ -41,8 +41,9 @@ namespace SqlSugar /// /// /// - ISugarQueryable WhereClass(List whereClassList,bool ignoreDefaultValue = false) where ClassType : class, new(); - + ISugarQueryable WhereClass(List whereClassList,bool ignoreDefaultValue = false) where ClassType : class, new(); + ISugarQueryable WhereClassByPrimaryKey(List list); + ISugarQueryable WhereClassByPrimaryKey(T data) ; ISugarQueryable Where(Expression> expression); ISugarQueryable Where(string whereString, object parameters = null); ISugarQueryable Where(List conditionalModels); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ISqlSugarClient.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ISqlSugarClient.cs index 4026507c4..0282d7d2b 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ISqlSugarClient.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ISqlSugarClient.cs @@ -116,6 +116,7 @@ namespace SqlSugar #endregion #region Saveable + IStorageable Storageable(List dataList) where T : class, new(); ISaveable Saveable(List saveObjects) where T : class, new(); ISaveable Saveable(T saveObject) where T : class, new(); #endregion diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IStorageable.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IStorageable.cs new file mode 100644 index 000000000..cced69317 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IStorageable.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; +namespace SqlSugar +{ + public interface IStorageable where T : class, new() + { + IStorageable WhereColumns(Expression> columns); + IStorageable SplitInsert(Func, bool> conditions, string message=null); + IStorageable SplitUpdate(Func, bool> conditions, string message = null); + IStorageable SplitError(Func, bool> conditions, string message = null); + IStorageable SplitIgnore(Func, bool> conditions, string message = null); + IStorageable SplitDelete(Func, bool> conditions, string message = null); + IStorageable SplitOther(Func, bool> conditions, string message = null); + StorageableResult ToStorage(); + } + + public class StorageableInfo where T : class, new() + { + public T Item { get; set; } + internal List Database { get; set; } + public bool Any(Func expression) + { + return Database.Any(expression); + } + public bool NotAny(Func expression) + { + return !Database.Any(expression); + } + } + + public class StorageableMessage : StorageableInfo where T : class, new() + { + public string StorageMessage { get; set; } + public StorageType? StorageType { get; set; } + } + + public enum StorageType + { + Insert=0, + Update=1, + Delete=2, + Error=3, + Other=4, + Ignore=5, + } + internal struct KeyValuePair + { + public TKey key; + public TValue value1; + public TValue2 value2; + public KeyValuePair(TKey key, TValue value1, TValue2 value2) + { + this.key = key; + this.value1 = value1; + this.value2 = value2; + } + } + + public class StorageableResult where T : class, new() + { + public List> TotalList { get; set; } + public List> InsertList { get; set; } + public List> UpdateList { get; set; } + public List> DeleteList { get; set; } + public List> ErrorList { get; set; } + public List> IgnoreList { get; set; } + public List> OtherList { get; set; } + public IInsertable AsInsertable { get; set; } + public IUpdateable AsUpdateable { get; set; } + public IDeleteable AsDeleteable { get; set; } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/PostgreSQL/DbMaintenance/PostgreSQLDbMaintenance.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/PostgreSQL/DbMaintenance/PostgreSQLDbMaintenance.cs index 9c789d4d3..1c3d82287 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/PostgreSQL/DbMaintenance/PostgreSQLDbMaintenance.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Realization/PostgreSQL/DbMaintenance/PostgreSQLDbMaintenance.cs @@ -237,9 +237,37 @@ namespace SqlSugar return "serial"; } } - #endregion + #endregion #region Methods + public override bool UpdateColumn(string tableName, DbColumnInfo columnInfo) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + var columnName= this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + string sql = GetUpdateColumnSql(tableName, columnInfo); + this.Context.Ado.ExecuteCommand(sql); + var isnull = columnInfo.IsNullable?" DROP NOT NULL ": " SET NOT NULL "; + this.Context.Ado.ExecuteCommand(string.Format("alter table {0} alter {1} {2}",tableName,columnName, isnull)); + return true; + } + + protected override string GetUpdateColumnSql(string tableName, DbColumnInfo columnInfo) + { + string columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string dataSize = GetSize(columnInfo); + string dataType = columnInfo.DataType; + if (!string.IsNullOrEmpty(dataType)) + { + dataType = " type " + dataType; + } + string nullType = ""; + string primaryKey = null; + string identity = null; + string result = string.Format(this.AlterColumnToTableSql, tableName, columnName, dataType, dataSize, nullType, primaryKey, identity); + return result; + } + /// ///by current connection string /// diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs index b808240c3..f21fb1915 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Dynamic; using System.Linq; using System.Linq.Expressions; @@ -337,6 +338,11 @@ namespace SqlSugar #endregion #region Saveable + + public IStorageable Storageable(List dataList) where T : class, new() + { + return this.Context.Storageable(dataList); + } public ISaveable Saveable(List saveObjects) where T : class, new() { return this.Context.Saveable(saveObjects); @@ -748,8 +754,17 @@ namespace SqlSugar } else { - IsSingleInstance = true; - result = NoSameThread(); + StackTrace st = new StackTrace(true); + var methods = st.GetFrames(); + var isAsync = UtilMethods.IsAnyAsyncMethod(methods); + if (isAsync) + { + result = Synchronization(); + } + else + { + result = NoSameThread(); + } } if (result.Root == null) { diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilMethods.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilMethods.cs index c979cdefb..df121e761 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilMethods.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilMethods.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; +using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; @@ -44,6 +45,42 @@ namespace SqlSugar } return value; } + public static bool IsAnyAsyncMethod(StackFrame[] methods) + { + bool isAsync = false; + foreach (var item in methods) + { + if (UtilMethods.IsAsyncMethod(item.GetMethod())) + { + isAsync = true; + } + } + return isAsync; + } + + public static bool IsAsyncMethod(MethodBase method) + { + if (method == null) + { + return false; + } + var name= method.Name; + if (name.Contains("OutputAsyncCausalityEvents")) + { + return true; + } + if (name.Contains("OutputWaitEtwEvents")) + { + return true; + } + if (name.Contains("ExecuteAsync")) + { + return true; + } + Type attType = typeof(AsyncStateMachineAttribute); + var attrib = (AsyncStateMachineAttribute)method.GetCustomAttribute(attType); + return (attrib != null); + } public static StackTraceInfo GetStackTrace() {