ZhiYeJianKang_PeiXun/cyqdata-master/Tool/Convert/ConvertTool.ChangeReaderToList.cs
2025-02-20 15:41:53 +08:00

253 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// 类型转换支持json转实体
/// </summary>
public static partial class ConvertTool
{
/// <summary>
/// DbDataReader To List
/// </summary>
internal static List<T> ChangeReaderToList<T>(DbDataReader reader)
{
Type t = typeof(T);
List<T> list = new List<T>();
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<string, Type> kv = new Dictionary<string, Type>(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<PropertyInfo> pInfoList = ReflectTool.GetPropertyList(t);
List<FieldInfo> fInfoList = ReflectTool.GetFieldList(t);
//SQLite 报错:该字符串未被识别为有效的 DateTime不能用sr[类型读]要用sdr.GetString读
// List<string> errIndex = new List<string>();//SQLite提供的dll不靠谱sdr[x]类型转不过时,会直接抛异常
Dictionary<string, int> errIndex = new Dictionary<string, int>();
while (reader.Read())
{
T obj = Activator.CreateInstance<T>();
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<default(T)>;
}
/// <summary>
/// DbDataReader To Json
/// </summary>
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<string> errIndex = new List<string>();//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();
}
}
}