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();
}
}
}