using CYQ.Data.Json; using CYQ.Data.SQL; using CYQ.Data.Table; using System; using System.Collections.Generic; using System.Data.Common; using System.Data.SqlTypes; using System.IO; using System.Reflection; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Web; namespace CYQ.Data.Tool { /// /// 类型转换(支持json转实体) /// public static partial class ConvertTool { /// /// DbDataReader To List /// internal static List ChangeReaderToList(DbDataReader reader) { Type t = typeof(T); List list = new List(); if (t.Name == "MDataRow") { MDataTable dt = reader; foreach (object row in dt.Rows) { list.Add((T)row); } } else if (reader != null) { #region Reader if (reader.HasRows) { Dictionary kv = new Dictionary(StringComparer.OrdinalIgnoreCase); for (int i = 0; i < reader.FieldCount; i++) { string key = reader.GetName(i); if (!kv.ContainsKey(key))//ado.net 底层bug,特殊情况会读出多余重复字段结构,见:https://q.cnblogs.com/q/143699/ { kv.Add(key, reader.GetFieldType(i)); } } List pInfoList = ReflectTool.GetPropertyList(t); List fInfoList = ReflectTool.GetFieldList(t); //SQLite 报错:该字符串未被识别为有效的 DateTime,不能用sr[类型读],要用sdr.GetString读 // List errIndex = new List();//SQLite提供的dll不靠谱,sdr[x]类型转不过时,会直接抛异常 Dictionary errIndex = new Dictionary(); while (reader.Read()) { T obj = Activator.CreateInstance(); if (pInfoList.Count > 0) { foreach (PropertyInfo p in pInfoList)//遍历实体 { if (p.CanWrite && kv.ContainsKey(p.Name)) { object objValue = null; try { if (errIndex.ContainsKey(p.Name)) { int index = errIndex[p.Name]; if (!reader.IsDBNull(index)) { objValue = reader.GetString(index); } } else { objValue = reader[p.Name]; } } catch { int index = reader.GetOrdinal(p.Name); if (!errIndex.ContainsKey(p.Name)) { errIndex.Add(p.Name, index); } objValue = reader.GetString(index); } if (objValue != null && objValue != DBNull.Value) { if (p.PropertyType != kv[p.Name] || errIndex.ContainsKey(p.Name)) { objValue = ChangeType(objValue, p.PropertyType);//尽量避免类型转换 } p.SetValue(obj, objValue, null); } } } } if (fInfoList.Count > 0) { foreach (FieldInfo f in fInfoList)//遍历实体 { if (kv.ContainsKey(f.Name)) { object objValue = null; try { if (errIndex.ContainsKey(f.Name)) { objValue = reader.GetString(errIndex[f.Name]); } else { objValue = reader[f.Name]; } } catch { int index = reader.GetOrdinal(f.Name); errIndex.Add(f.Name, index); objValue = reader.GetString(index); } if (objValue != null && objValue != DBNull.Value) { if (f.FieldType != kv[f.Name] || errIndex.ContainsKey(f.Name)) { objValue = ChangeType(objValue, f.FieldType);//尽量避免类型转换 } f.SetValue(obj, objValue); } } } } list.Add(obj); } kv.Clear(); kv = null; errIndex.Clear(); errIndex = null; } reader.Close(); reader.Dispose(); reader = null; #endregion } return list; //return List; } /// /// DbDataReader To Json /// internal static string ChangeReaderToJson(DbDataReader reader, JsonHelper js, bool needCheckHiddenField) { if (js == null) { js = new JsonHelper(false, false); } if (reader != null) { bool[] isBool = new bool[reader.FieldCount]; bool[] isDateTime = new bool[reader.FieldCount]; bool[] isNoQuotes = new bool[reader.FieldCount]; bool[] isHiddenField = new bool[reader.FieldCount]; string hiddenFields = "," + AppConfig.DB.HiddenFields.ToLower() + ","; for (int i = 0; i < reader.FieldCount; i++) { if (needCheckHiddenField) { isHiddenField[i] = hiddenFields.IndexOf("," + reader.GetName(i) + ",", StringComparison.OrdinalIgnoreCase) > -1; } switch (DataType.GetGroup(DataType.GetSqlType(reader.GetFieldType(i)))) { case DataGroupType.Bool: isBool[i] = true; isNoQuotes[i] = true; break; case DataGroupType.Number: isNoQuotes[i] = true; break; case DataGroupType.Date: isDateTime[i] = true; break; } } #region Reader //SQLite 报错:该字符串未被识别为有效的 DateTime,不能用sr[类型读],要用sdr.GetString读 // List errIndex = new List();//SQLite提供的dll不靠谱,sdr[x]类型转不过时,会直接抛异常 bool[] errIndex = new bool[reader.FieldCount]; if (reader.HasRows) { while (reader.Read()) { js.RowCount++; for (int i = 0; i < reader.FieldCount; i++) { if (isHiddenField[i]) { continue; } object objValue = null; try { if (errIndex[i]) { objValue = reader.GetString(i); } else { objValue = reader.GetValue(i); } } catch { errIndex[i] = true; objValue = reader.GetString(i); } if (isDateTime[i]) { DateTime dt; if (DateTime.TryParse(Convert.ToString(objValue), out dt)) { objValue = dt.ToString(js.DateTimeFormatter); } } else if (isBool[i]) { objValue = objValue.ToString().ToLower(); } js.Add(reader.GetName(i), Convert.ToString(objValue), isNoQuotes[i]); } js.AddBr(); } } reader.Close(); reader.Dispose(); reader = null; #endregion } return js.ToString(); } } }