using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SqlSugar { public class StorageableDataTable { internal DataTable DataTable { get; set; } internal SqlSugarProvider Context { get; set; } internal string[] Columns { get; set; } = new string[] { }; internal string SugarGroupId = "SugarGroupId"; internal string SugarUpdateRows = "SugarUpdateRows"; internal string SugarColumns = "SugarColumns"; internal string SugarErrorMessage = "SugarErrorMessage"; internal List dbDataList = new List(); List,string>> whereFuncs = new List,string>>(); public StorageableDataTable WhereColumns(string name) { return WhereColumns(new string[] { name}); } public StorageableDataTable WhereColumns(string[] names) { this.Columns = names; var queryable = this.Context.Queryable(); Check.Exception(Columns==null|| Columns.Length==0,"need WhereColums"); var tableName = queryable.SqlBuilder.GetTranslationTableName(DataTable.TableName); this.Context.Utilities.PageEach(DataTable.Rows.Cast(), 200, itemList => { List conditList = new List(); SetConditList(itemList, Columns, conditList); var addItem = this.Context.Queryable().AS(tableName).Where(conditList).ToDataTable().Rows.Cast().ToList(); this.dbDataList.AddRange(addItem); }); return this; } public StorageableDataTable WhereColumns(List names) { return WhereColumns(names.ToArray()); } public StorageableDataTable SplitInsert(Func conditions, string message = null) { whereFuncs.Add(new KeyValuePair, string>(StorageType.Insert, conditions,message)); return this; } public StorageableDataTable SplitDelete(Func conditions, string message = null) { whereFuncs.Add(new KeyValuePair,string>(StorageType.Delete, conditions,message)); return this; } public StorageableDataTable SplitUpdate(Func conditions, string message = null) { whereFuncs.Add(new KeyValuePair,string>(StorageType.Update, conditions,message)); return this; } public StorageableDataTable Saveable(string inserMessage = null, string updateMessage = null) { SplitUpdate(it => it.Any(), updateMessage); SplitInsert(it => true, inserMessage); return this; } public StorageableDataTable SplitError(Func conditions, string message = null) { whereFuncs.Add(new KeyValuePair, string>(StorageType.Error, conditions, message)); return this; } public StorageableDataTable SplitIgnore(Func conditions, string message = null) { whereFuncs.Add(new KeyValuePair, string>(StorageType.Ignore, conditions, message)); return this; } public DataTableResult ToStorage() { if (whereFuncs == null || whereFuncs.Count == 0) { Saveable(); } foreach (DataRow row in DataTable.Rows) { foreach (var item in whereFuncs.OrderByDescending(it => (int)it.key)) { SplitMethod(item.value1,item.key,row,item.value2); } if (row[SugarGroupId] == null || row[SugarGroupId] == DBNull.Value) { row[SugarGroupId] = StorageType.Ignore; } } DataTable.Columns.Remove(SugarUpdateRows); DataTable.Columns.Remove(SugarColumns); var Groups=DataTable.Rows.Cast() .Where(it=> it[SugarGroupId]!=null&& it[SugarGroupId] != DBNull.Value) .GroupBy(it => ((StorageType)it[SugarGroupId]).ToString()).Select(it=>new DataTableGroups{ Type=it.Key,DataTable= it.CopyToDataTable() }) .ToList(); DataTable.Columns.Remove(SugarGroupId); DataTable.Columns.Remove(SugarErrorMessage); var inserList = new List>(); var updateList = new List>(); var DeleteList=Groups.FirstOrDefault(it=>it.Type==StorageType.Delete.ToString()); if (Groups.Any(it => it.Type == StorageType.Insert.ToString())) { foreach (var item in Groups) { if (item.Type == StorageType.Insert.ToString()) { item.DataTable.Columns.Remove(SugarGroupId); item.DataTable.Columns.Remove(SugarErrorMessage); inserList.AddRange(this.Context.Utilities.DataTableToDictionaryList(item.DataTable)); } } } if (Groups.Any(it => it.Type == StorageType.Update.ToString())) { foreach (var item in Groups) { if (item.Type == StorageType.Update.ToString()) { item.DataTable.Columns.Remove(SugarGroupId); item.DataTable.Columns.Remove(SugarErrorMessage); updateList.AddRange(this.Context.Utilities.DataTableToDictionaryList(item.DataTable)); } } } List conditionalModels = new List(); if (DeleteList!=null) { SetConditList(DeleteList.DataTable.Rows.Cast().ToList(), Columns, conditionalModels); } var tableName = this.Context.Queryable().SqlBuilder.GetTranslationTableName(DataTable.TableName); DataTableResult result = new DataTableResult() { DataTableGroups=Groups, AsDeleteable=this.Context.Deleteable().AS(tableName).Where(conditionalModels), AsUpdateable= this.Context.Updateable(updateList).AS(tableName).WhereColumns(Columns), AsInsertable=this.Context.Insertable(inserList).AS(tableName) }; return result; } private void SplitMethod(Func conditions, StorageType type,DataRow item,string message) { item[SugarColumns] = Columns; item[SugarUpdateRows] = dbDataList; if ((item[SugarGroupId]==null|| item[SugarGroupId] == DBNull.Value) && conditions(item)) { item[SugarGroupId] = type; item[SugarErrorMessage] = message; } } private void SetConditList(List itemList, string[] whereColumns, List conditList) { ; foreach (var dataItem in itemList) { var condition = new ConditionalCollections() { ConditionalList = new List>() }; conditList.Add(condition); int i = 0; foreach (var name in whereColumns) { var value = dataItem[name]; if (value != null && value.GetType().IsEnum()) { value = Convert.ToInt64(value); } condition.ConditionalList.Add(new KeyValuePair(i == 0 ? WhereType.Or : WhereType.And, new ConditionalModel() { FieldName = name, ConditionalType = ConditionalType.Equal, FieldValue = value + "", FieldValueConvertFunc = this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL ? UtilMethods.GetTypeConvert(value) : null })); ++i; } } } } public class DataTableResult { public List DataTableGroups { get; set; } public IUpdateable> AsUpdateable { get; set; } public IDeleteable AsDeleteable { get; set; } public IInsertable> AsInsertable { get; set; } } public class DataTableGroups { public string Type { get; set; } public DataTable DataTable { get; set; } } public static class StorageableDataTableExtensions { public static bool Any(this DataRow row) { var list=row["SugarUpdateRows"] as List; var columns = row["SugarColumns"] as string[]; return list.Any(it => { var result = true; foreach (var name in columns) { if (result) { result = row[name].ObjToString() == it[name].ObjToString(); if (result==false&&it[name] != null && it[name].GetType() == UtilConstants.DecType) { result= row[name].ObjToDecimal() == it[name].ObjToDecimal(); } if (result == false) { break; } } } return result; }); } } }