using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SqlSugar { public partial class DbBindAccessory { public QueryBuilder QueryBuilder { get; set; } protected List GetEntityList(SqlSugarProvider context, IDataReader dataReader) { Type type = typeof(T); string types = null; var fieldNames = GetDataReaderNames(dataReader,ref types); string cacheKey = GetCacheKey(type,fieldNames) + types; var dataAfterFunc = context.CurrentConnectionConfig?.AopEvents?.DataExecuted; IDataReaderEntityBuilder entytyList = context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, () => { var cacheResult = new IDataReaderEntityBuilder(context, dataReader,fieldNames).CreateBuilder(type); return cacheResult; }); List result = new List(); try { if (dataReader == null) return result; while (dataReader.Read()) { //try //{ result.Add(entytyList.Build(dataReader)); //} //catch (Exception ex) //{ // Check.Exception(true, ErrorMessage.EntityMappingError, ex.Message); //} SetAppendColumns(dataReader); } ExecuteDataAfterFun(context, dataAfterFunc, result); } catch(Exception ex) { if (ex.Message == "Common Language Runtime detected an invalid program.") { Check.Exception(true, ErrorMessage.EntityMappingError, ex.Message); } else { throw; } } return result; } protected async Task> GetEntityListAsync(SqlSugarProvider context, IDataReader dataReader) { Type type = typeof(T); string types = null; var fieldNames = GetDataReaderNames(dataReader,ref types); string cacheKey = GetCacheKey(type, fieldNames)+types; var dataAfterFunc = context.CurrentConnectionConfig?.AopEvents?.DataExecuted; IDataReaderEntityBuilder entytyList = context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, () => { var cacheResult = new IDataReaderEntityBuilder(context, dataReader, fieldNames).CreateBuilder(type); return cacheResult; }); List result = new List(); try { if (dataReader == null) return result; while (await((DbDataReader)dataReader).ReadAsync()) { //try //{ result.Add(entytyList.Build(dataReader)); //} //catch (Exception ex) //{ // Check.Exception(true, ErrorMessage.EntityMappingError, ex.Message); //} SetAppendColumns(dataReader); } ExecuteDataAfterFun(context, dataAfterFunc, result); } catch (Exception ex) { if (ex.Message == "Common Language Runtime detected an invalid program.") { Check.Exception(true, ErrorMessage.EntityMappingError, ex.Message); } else { throw; } } return result; } private static void ExecuteDataAfterFun(SqlSugarProvider context, Action dataAfterFunc, List result) { if (dataAfterFunc != null) { var entity = context.EntityMaintenance.GetEntityInfo(); foreach (var item in result) { dataAfterFunc(item, new DataAfterModel() { EntityColumnInfos = entity.Columns, Entity = entity, EntityValue = item }); } } } private string GetCacheKey(Type type,List keys) { StringBuilder sb = new StringBuilder("DataReaderToList."); sb.Append(type.FullName); sb.Append("."); foreach (var item in keys) { sb.Append(item); } return sb.ToString(); } private void SetAppendColumns(IDataReader dataReader) { if (QueryBuilder != null && QueryBuilder.AppendColumns != null && QueryBuilder.AppendColumns.Any()) { if (QueryBuilder.AppendValues == null) QueryBuilder.AppendValues = new List>(); List addItems = new List(); foreach (var item in QueryBuilder.AppendColumns) { var vi = dataReader.GetOrdinal(item.AsName); var value = dataReader.GetValue(vi); addItems.Add(new QueryableAppendColumn() { Name = item.Name, AsName = item.AsName, Value = value }); } QueryBuilder.AppendValues.Add(addItems); } } private List GetDataReaderNames(IDataReader dataReader,ref string types) { List keys = new List(); StringBuilder sbTypes = new StringBuilder(); var count = dataReader.FieldCount; for (int i = 0; i < count; i++) { keys.Add(dataReader.GetName(i)); var type = dataReader.GetFieldType(i); if (type != null) { sbTypes.Append(type.Name.Substring(0, 2)); } } types = sbTypes.ToString(); return keys; } protected List GetKeyValueList(Type type, IDataReader dataReader) { List result = new List(); while (dataReader.Read()) { GetKeyValueList(type, dataReader, result); } return result; } protected async Task> GetKeyValueListAsync(Type type, IDataReader dataReader) { List result = new List(); while (await ((DbDataReader)dataReader).ReadAsync()) { GetKeyValueList(type, dataReader, result); } return result; } private static void GetKeyValueList(Type type, IDataReader dataReader, List result) { if (UtilConstants.DicOO == type) { var kv = new KeyValuePair(dataReader.GetValue(0), dataReader.GetValue(1)); result.Add((T)Convert.ChangeType(kv, typeof(KeyValuePair))); } else if (UtilConstants.DicIS == type) { var kv = new KeyValuePair(dataReader.GetValue(0).ObjToInt(), dataReader.GetValue(1).ObjToString()); result.Add((T)Convert.ChangeType(kv, typeof(KeyValuePair))); } else if (UtilConstants.Dicii == type) { var kv = new KeyValuePair(dataReader.GetValue(0).ObjToInt(), dataReader.GetValue(1).ObjToInt()); result.Add((T)Convert.ChangeType(kv, typeof(KeyValuePair))); } else if (UtilConstants.DicSi == type) { var kv = new KeyValuePair(dataReader.GetValue(0).ObjToString(), dataReader.GetValue(1).ObjToInt()); result.Add((T)Convert.ChangeType(kv, typeof(KeyValuePair))); } else if (UtilConstants.DicSo == type) { var kv = new KeyValuePair(dataReader.GetValue(0).ObjToString(), dataReader.GetValue(1)); result.Add((T)Convert.ChangeType(kv, typeof(KeyValuePair))); } else if (UtilConstants.DicSS == type) { var kv = new KeyValuePair(dataReader.GetValue(0).ObjToString(), dataReader.GetValue(1).ObjToString()); result.Add((T)Convert.ChangeType(kv, typeof(KeyValuePair))); } else { Check.Exception(true, ErrorMessage.NotSupportedDictionary); } } protected async Task> GetArrayListAsync(Type type, IDataReader dataReader) { List result = new List(); int count = dataReader.FieldCount; var childType = type.GetElementType(); while (await((DbDataReader)dataReader).ReadAsync()) { GetArrayList(type, dataReader, result, count, childType); } return result; } protected List GetArrayList(Type type, IDataReader dataReader) { List result = new List(); int count = dataReader.FieldCount; var childType = type.GetElementType(); while (dataReader.Read()) { GetArrayList(type, dataReader, result, count, childType); } return result; } private static void GetArrayList(Type type, IDataReader dataReader, List result, int count, Type childType) { object[] array = new object[count]; for (int i = 0; i < count; i++) { array[i] = Convert.ChangeType(dataReader.GetValue(i), childType); } if (childType == UtilConstants.StringType) result.Add((T)Convert.ChangeType(array.Select(it => it.ObjToString()).ToArray(), type)); else if (childType == UtilConstants.ObjType) result.Add((T)Convert.ChangeType(array.Select(it => it == DBNull.Value ? null : (object)it).ToArray(), type)); else if (childType == UtilConstants.BoolType) result.Add((T)Convert.ChangeType(array.Select(it => it.ObjToBool()).ToArray(), type)); else if (childType == UtilConstants.ByteType) result.Add((T)Convert.ChangeType(array.Select(it => it == DBNull.Value ? 0 : (byte)it).ToArray(), type)); else if (childType == UtilConstants.DecType) result.Add((T)Convert.ChangeType(array.Select(it => it.ObjToDecimal()).ToArray(), type)); else if (childType == UtilConstants.GuidType) result.Add((T)Convert.ChangeType(array.Select(it => it == DBNull.Value ? Guid.Empty : (Guid)it).ToArray(), type)); else if (childType == UtilConstants.DateType) result.Add((T)Convert.ChangeType(array.Select(it => it == DBNull.Value ? DateTime.MinValue : (DateTime)it).ToArray(), type)); else if (childType == UtilConstants.IntType) result.Add((T)Convert.ChangeType(array.Select(it => it.ObjToInt()).ToArray(), type)); else Check.Exception(true, ErrorMessage.NotSupportedArray); } protected List GetValueTypeList(Type type, IDataReader dataReader) { List result = new List(); while (dataReader.Read()) { GetValueTypeList(type, dataReader, result); } return result; } protected async Task> GetValueTypeListAsync(Type type, IDataReader dataReader) { List result = new List(); while (await ((DbDataReader)dataReader).ReadAsync()) { GetValueTypeList(type, dataReader, result); } return result; } private static void GetValueTypeList(Type type, IDataReader dataReader, List result) { var value = dataReader.GetValue(0); if (type == UtilConstants.GuidType) { value = Guid.Parse(value.ToString()); } if (value == DBNull.Value) { result.Add(default(T)); } else if (type.IsEnum) { result.Add((T)Enum.Parse(type, value.ObjToString())); } else { result.Add((T)Convert.ChangeType(value, UtilMethods.GetUnderType(type))); } } } }