253 lines
11 KiB
C#
253 lines
11 KiB
C#
|
|
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();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|