动态实体绑定 主要有以下两种

1、表达式树构建委托

2、Emit构建委托

根据我的经验 Emit 代码量可以更少可以很好实现代码复用

Emit实践开源项目地址跳转 https://www.cnblogs.com/China-Mr-zhong/p/17514567.html 查看

using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection; namespace Fast.Framework.Extensions
{ /// <summary>
/// 可空扩展类
/// </summary>
public static class NullableExtensions
{ /// <summary>
/// 到Nullable
/// </summary>
private static readonly Dictionary<Type, MethodInfo> toNullableCache; /// <summary>
/// 构造方法
/// </summary>
static NullableExtensions()
{
toNullableCache = new Dictionary<Type, MethodInfo>()
{
{ typeof(short),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(short) })},
{ typeof(ushort),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(ushort) })},
{ typeof(int),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(int) })},
{ typeof(uint),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(uint) })},
{ typeof(long),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(long) })},
{ typeof(ulong),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(ulong) })},
{ typeof(float),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(float) })},
{ typeof(double),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(double) })},
{ typeof(decimal),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(decimal) })},
{ typeof(char),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(char) })},
{ typeof(byte),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(byte) })},
{ typeof(sbyte),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(sbyte) })},
{ typeof(bool),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(bool) })},
{ typeof(string),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(string) })},
{ typeof(DateTime),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(DateTime) })},
{ typeof(DateTimeOffset),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(DateTimeOffset) })},
{ typeof(TimeSpan),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(TimeSpan) })},
{ typeof(Guid),typeof(NullableExtensions).GetMethod(nameof(ToNullable), new Type[] { typeof(Guid) })},
};
} /// <summary>
/// 获取ToNullable方法信息
/// </summary>
/// <param name="type">类型</param>
/// <returns></returns>
public static MethodInfo GetToNullableMethodInfo(this Type type)
{
if (!toNullableCache.ContainsKey(type))
{
throw new NotSupportedException($"类型:{type.Name}暂不支持转换");
}
return toNullableCache[type];
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static short? ToNullable(short value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static ushort? ToNullable(ushort value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static int? ToNullable(int value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static uint? ToNullable(uint value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static long? ToNullable(long value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static ulong? ToNullable(ulong value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static float? ToNullable(float value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static double? ToNullable(double value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static decimal? ToNullable(decimal value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static char? ToNullable(char value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static byte? ToNullable(byte value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static sbyte? ToNullable(sbyte value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static bool? ToNullable(bool value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static DateTime? ToNullable(DateTime value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static DateTimeOffset? ToNullable(DateTimeOffset value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static TimeSpan? ToNullable(TimeSpan value)
{
return value;
} /// <summary>
/// 到Nullable
/// </summary>
/// <param name="value">值</param>
/// <returns></returns>
public static Guid? ToNullable(Guid value)
{
return value;
}
} }
using System;
using System.Text;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using Fast.Framework.Cache;
using System.Data;
using Fast.Framework.Utils;
using System.Text.Json;
using Fast.Framework.Exceptions;
using Fast.Framework.Models;
using System.Reflection.Emit; namespace Fast.Framework.Extensions
{ /// <summary>
/// DbDataReader扩展类
/// </summary>
public static class DbDataReaderExtensions
{
/// <summary>
/// 获取方法信息缓存
/// </summary>
private static readonly Dictionary<Type, MethodInfo> getMethodInfoCache; /// <summary>
/// 转换方法信息
/// </summary>
private static readonly Dictionary<Type, ConvertInfo> convertMethodInfos; /// <summary>
/// 是否DBNull方法信息
/// </summary>
private static readonly MethodInfo isDBNullMethodInfo; /// <summary>
/// 是否空或空格字符串方法信息
/// </summary>
private static readonly MethodInfo isNullOrWhiteSpaceMethodInfo; /// <summary>
/// Guid到字符串
/// </summary>
private static readonly MethodInfo guidToStringMethodInfo; /// <summary>
/// 静态构造方法
/// </summary>
static DbDataReaderExtensions()
{
var getValueMethod = typeof(IDataRecord).GetMethod(nameof(IDataRecord.GetValue), new Type[] { typeof(int) }); isDBNullMethodInfo = typeof(IDataRecord).GetMethod(nameof(IDataRecord.IsDBNull), new Type[] { typeof(int) }); isNullOrWhiteSpaceMethodInfo = typeof(string).GetMethod(nameof(string.IsNullOrWhiteSpace), new Type[] { typeof(string) }); guidToStringMethodInfo = typeof(Guid).GetMethod(nameof(Guid.ToString), new Type[] { typeof(Guid) }); getMethodInfoCache = new Dictionary<Type, MethodInfo>()
{
{ typeof(object),getValueMethod},
{ typeof(short),typeof(IDataRecord).GetMethod(nameof(IDataRecord.GetInt16), new Type[] { typeof(int) })},
{ typeof(ushort),getValueMethod},
{ typeof(int),typeof(IDataRecord).GetMethod(nameof(IDataRecord.GetInt32), new Type[] { typeof(int) })},
{ typeof(uint),getValueMethod},
{ typeof(long),typeof(IDataRecord).GetMethod(nameof(IDataRecord.GetInt64), new Type[] { typeof(int) })},
{ typeof(ulong),getValueMethod},
{ typeof(float),typeof(IDataRecord).GetMethod(nameof(IDataRecord.GetFloat), new Type[] { typeof(int) })},
{ typeof(double),typeof(IDataRecord).GetMethod(nameof(IDataRecord.GetDouble), new Type[] { typeof(int) })},
{ typeof(decimal),typeof(IDataRecord).GetMethod(nameof(IDataRecord.GetDecimal), new Type[] { typeof(int) })},
{ typeof(char),typeof(IDataRecord).GetMethod(nameof(IDataRecord.GetChar), new Type[] { typeof(int) })},
{ typeof(byte),typeof(IDataRecord).GetMethod(nameof(IDataRecord.GetByte), new Type[] { typeof(int) })},
{ typeof(sbyte),getValueMethod},
{ typeof(bool),typeof(IDataRecord).GetMethod(nameof(IDataRecord.GetBoolean),new Type[]{ typeof(int)})},
{ typeof(string),typeof(IDataRecord).GetMethod(nameof(IDataRecord.GetString),new Type[]{ typeof(int)})},
{ typeof(DateTime),typeof(IDataRecord).GetMethod(nameof(IDataRecord.GetDateTime),new Type[]{ typeof(int)})},
{ typeof(TimeSpan),typeof(IDataRecord).GetMethod(nameof(IDataRecord.GetValue),new Type[]{ typeof(int)})},
{ typeof(Guid),typeof(IDataRecord).GetMethod(nameof(IDataRecord.GetGuid),new Type[]{ typeof(int)})}
}; convertMethodInfos = new Dictionary<Type, ConvertInfo>()
{
{ typeof(short),new ConvertInfo()
{
TargetType=typeof(Convert),
MethodName=nameof(Convert.ToInt16)
}
},
{ typeof(ushort),new ConvertInfo()
{
TargetType=typeof(Convert),
MethodName=nameof(Convert.ToUInt16)
}
},
{ typeof(int),new ConvertInfo()
{
TargetType=typeof(Convert),
MethodName=nameof(Convert.ToInt32)
}
},
{ typeof(uint),new ConvertInfo()
{
TargetType=typeof(Convert),
MethodName=nameof(Convert.ToUInt32)
}
},
{ typeof(long),new ConvertInfo()
{
TargetType=typeof(Convert),
MethodName=nameof(Convert.ToInt64)
}
},
{ typeof(ulong),new ConvertInfo()
{
TargetType=typeof(Convert),
MethodName=nameof(Convert.ToUInt64)
}
},
{ typeof(float),new ConvertInfo()
{
TargetType=typeof(Convert),
MethodName=nameof(Convert.ToSingle)
}
},
{ typeof(double),new ConvertInfo()
{
TargetType=typeof(Convert),
MethodName=nameof(Convert.ToDouble)
}
},
{ typeof(decimal),new ConvertInfo()
{
TargetType=typeof(Convert),
MethodName=nameof(Convert.ToDecimal)
} },
{ typeof(char),new ConvertInfo()
{
TargetType=typeof(Convert),
MethodName=nameof(Convert.ToChar)
}
},
{ typeof(byte),new ConvertInfo()
{
TargetType=typeof(Convert),
MethodName=nameof(Convert.ToByte)
}
},
{ typeof(sbyte),new ConvertInfo()
{
TargetType=typeof(Convert),
MethodName=nameof(Convert.ToSByte)
}
},
{ typeof(bool),new ConvertInfo()
{
TargetType=typeof(Convert),
MethodName=nameof(Convert.ToBoolean)
}
},
{ typeof(string),new ConvertInfo()
{
TargetType=typeof(Convert),
MethodName=nameof(Convert.ToString)
}
},
{ typeof(DateTime),new ConvertInfo()
{
TargetType=typeof(Convert),
MethodName=nameof(Convert.ToDateTime)
}
},
{ typeof(Guid),new ConvertInfo()
{
TargetType=typeof(Guid),
MethodName=nameof(Guid.Parse)
}
}
};
} /// <summary>
/// 快速设置值
/// </summary>
/// <param name="il">IL</param>
/// <param name="dbColumn">数据库列</param>
/// <param name="type">类型</param>
/// <param name="type">是否Json</param>
private static void FastSetValue(ILGenerator il, DbColumn dbColumn, Type type, bool isJson = false)
{
var getValueMethodInfo = getMethodInfoCache[dbColumn.DataType];
var underlyingType = Nullable.GetUnderlyingType(type);
var isNullable = false;
if (underlyingType != null)
{
isNullable = true;
}
else
{
underlyingType = type;
} il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldc_I4, dbColumn.ColumnOrdinal.Value);
il.Emit(OpCodes.Callvirt, getValueMethodInfo); if (isJson)
{
if (!getValueMethodInfo.ReturnType.Equals(typeof(string)))
{
throw new FastException($"数据库列{dbColumn.ColumnName}不是字符串类型不支持Json序列化.");
}
var ifLabel = il.DefineLabel();
var endIfLabel = il.DefineLabel();
il.Emit(OpCodes.Call, isNullOrWhiteSpaceMethodInfo);
il.Emit(OpCodes.Brtrue_S, ifLabel);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldc_I4, dbColumn.ColumnOrdinal.Value);
il.Emit(OpCodes.Callvirt, getValueMethodInfo);
il.Emit(OpCodes.Ldnull);
var deserializeGenericMethodInfo = typeof(Json).GetMethod(nameof(Json.Deserialize));
var deserializeMethodInfo = deserializeGenericMethodInfo.MakeGenericMethod(type);
il.Emit(OpCodes.Call, deserializeMethodInfo);
il.Emit(OpCodes.Br_S, endIfLabel);
il.MarkLabel(ifLabel);
il.Emit(OpCodes.Ldnull);
il.MarkLabel(endIfLabel);
}
else
{
var returnType = getValueMethodInfo.ReturnType;
if (returnType.Equals(typeof(float)) || returnType.Equals(typeof(double)) || returnType.Equals(typeof(decimal)))
{
var v = il.DeclareLocal(returnType);
il.Emit(OpCodes.Stloc_S, v);
il.Emit(OpCodes.Ldloca_S, v);
il.Emit(OpCodes.Ldstr, "G0");
var converMethodInfo = returnType.GetMethod("ToString", new Type[] { typeof(string) });
il.Emit(OpCodes.Call, converMethodInfo);
returnType = typeof(string);
}
if (!underlyingType.Equals(returnType))//底层类型不等于值类型转换处理
{
if (dbColumn.DataType.Equals(typeof(Guid)) && underlyingType.Equals(typeof(string)))
{
il.Emit(OpCodes.Callvirt, guidToStringMethodInfo);//Guid转字符串
}
else
{
if (!convertMethodInfos.ContainsKey(underlyingType))
{
throw new NotSupportedException($"{nameof(underlyingType)}暂不支持转换.");
}
var converInfo = convertMethodInfos[underlyingType];
var converMethodInfo = converInfo.TargetType.GetMethod(converInfo.MethodName, new Type[] { returnType });
if (converMethodInfo.IsVirtual)
{
il.Emit(OpCodes.Callvirt, converMethodInfo);
}
else
{
il.Emit(OpCodes.Call, converMethodInfo);
}
}
} if (isNullable)//可空类型转换
{
il.Emit(OpCodes.Call, underlyingType.GetToNullableMethodInfo());
}
}
} /// <summary>
/// 快速设置值
/// </summary>
/// <param name="result">结果</param>
/// <param name="il">IL</param>
/// <param name="dbColumn">数据库列</param>
/// <param name="columnInfo">列信息</param>
private static void FastSetValue(LocalBuilder result, ILGenerator il, DbColumn dbColumn, ColumnInfo columnInfo)
{
il.Emit(OpCodes.Ldloc, result);
FastSetValue(il, dbColumn, columnInfo.MemberType, columnInfo.IsJson);
if (columnInfo.IsField)
{
il.Emit(OpCodes.Stfld, columnInfo.FieldInfo);
}
else
{
il.Emit(OpCodes.Callvirt, columnInfo.PropertyInfo.SetMethod);
}
} /// <summary>
/// 初始化默认值
/// </summary>
/// <param name="il">IL</param>
/// <param name="type">类型</param>
private static void InitDeafultValue(ILGenerator il, Type type)
{
var v = il.DeclareLocal(type);
il.Emit(OpCodes.Ldloca_S, v);
il.Emit(OpCodes.Initobj, type);
il.Emit(OpCodes.Ldloc_S, v);
} /// <summary>
/// 创建快速设置值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dbColumns">数据库列</param>
/// <returns></returns>
public static Func<IDataReader, T> CreateFastSetValue<T>(this ReadOnlyCollection<DbColumn> dbColumns)
{
var type = typeof(T);
var keys = dbColumns.Select(s =>
{
if (s.AllowDBNull == null)
{
return $"{s.ColumnName}_{s.DataTypeName}_True";
}
else
{
return $"{s.ColumnName}_{s.DataTypeName}_{s.AllowDBNull}";
}
}); var cacheKey = $"{nameof(CreateFastSetValue)}_{type.GUID}_{string.Join(",", keys)}"; return StaticCache<Func<IDataReader, T>>.GetOrAdd(cacheKey, () =>
{
var method = new DynamicMethod("FastEntity", type, new Type[] { typeof(IDataReader) }, type, true);
var il = method.GetILGenerator();
var result = il.DeclareLocal(type);
if (type.IsClass())
{
var entityInfo = type.GetEntityInfo();
if (entityInfo.IsAnonymousType)
{
//success
foreach (var dbColumn in dbColumns)
{
var columnInfo = entityInfo.ColumnInfos.FirstOrDefault(f => f.ColumnName == dbColumn.ColumnName);
if (columnInfo == null)
{
InitDeafultValue(il, entityInfo.ColumnInfos[dbColumn.ColumnOrdinal.Value].MemberType);
}
else
{
if (dbColumn.AllowDBNull == null || dbColumn.AllowDBNull.Value)
{
var ifLabel = il.DefineLabel();
var endIfLabel = il.DefineLabel();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldc_I4, dbColumn.ColumnOrdinal.Value);
il.Emit(OpCodes.Callvirt, isDBNullMethodInfo);
il.Emit(OpCodes.Brtrue_S, ifLabel);
FastSetValue(il, dbColumn, columnInfo.MemberType, columnInfo.IsJson);
il.Emit(OpCodes.Br_S, endIfLabel);
il.MarkLabel(ifLabel);
InitDeafultValue(il, columnInfo.MemberType);
il.MarkLabel(endIfLabel);
}
else
{
FastSetValue(il, dbColumn, columnInfo.MemberType, columnInfo.IsJson);
}
}
}
var memberTypes = entityInfo.ColumnInfos.Select(s => s.MemberType).ToArray();
var constructorInfo = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, memberTypes);
il.Emit(OpCodes.Newobj, constructorInfo);
il.Emit(OpCodes.Stloc, result);
}
else
{
//success
var constructorInfo = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, Type.EmptyTypes);
il.Emit(OpCodes.Newobj, constructorInfo);
il.Emit(OpCodes.Stloc, result);
foreach (var dbColumn in dbColumns)
{
var columnInfo = entityInfo.ColumnInfos.FirstOrDefault(f => f.ColumnName == dbColumn.ColumnName);
if (columnInfo != null)
{
if (!getMethodInfoCache.ContainsKey(dbColumn.DataType))
{
throw new NotSupportedException($"数据类型:{dbColumn.DataType}暂不支持绑定.");
}
if (dbColumn.AllowDBNull == null || dbColumn.AllowDBNull.Value)
{
var endIfLabel = il.DefineLabel();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldc_I4, dbColumn.ColumnOrdinal.Value);
il.Emit(OpCodes.Callvirt, isDBNullMethodInfo);
il.Emit(OpCodes.Brtrue, endIfLabel);
FastSetValue(result, il, dbColumn, columnInfo);
il.MarkLabel(endIfLabel);
}
else
{
FastSetValue(result, il, dbColumn, columnInfo);
}
}
}
}
il.Emit(OpCodes.Ldloc, result);
il.Emit(OpCodes.Ret);
}
else
{
//success
if (dbColumns[0].AllowDBNull == null || dbColumns[0].AllowDBNull.Value)
{
var endIfLabel = il.DefineLabel();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldc_I4, dbColumns[0].ColumnOrdinal.Value);
il.Emit(OpCodes.Callvirt, isDBNullMethodInfo);
il.Emit(OpCodes.Brtrue, endIfLabel);
FastSetValue(il, dbColumns[0], typeof(T));
il.Emit(OpCodes.Stloc, result);
il.MarkLabel(endIfLabel);
}
else
{
FastSetValue(il, dbColumns[0], typeof(T));
il.Emit(OpCodes.Stloc, result);
}
il.Emit(OpCodes.Ldloc, result);
il.Emit(OpCodes.Ret);
}
return method.CreateDelegate<Func<IDataReader, T>>();
});
} /// <summary>
/// 最终处理
/// </summary>
/// <param name="reader">阅读器</param>
/// <returns></returns>
private static void FinalProcessing(this DbDataReader reader)
{
if (!reader.NextResult())
{
reader.Close();
}
} /// <summary>
/// 最终处理异步
/// </summary>
/// <param name="reader">阅读器</param>
/// <returns></returns>
private static async Task FinalProcessingAsync(this DbDataReader reader)
{
if (!await reader.NextResultAsync())
{
await reader.CloseAsync();
}
} /// <summary>
/// 第一构建
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dataReader">数据读取</param>
/// <returns></returns>
public static T FirstBuild<T>(this DbDataReader dataReader)
{
var reader = dataReader;
var dbColumns = reader.GetColumnSchema();
T t = default;
if (reader.Read())
{
var func = dbColumns.CreateFastSetValue<T>();
t = func.Invoke(reader);
}
reader.FinalProcessing();
return t;
} /// <summary>
/// 第一构建异步
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dataReader">数据读取</param>
/// <returns></returns>
public static async Task<T> FirstBuildAsync<T>(this Task<DbDataReader> dataReader)
{
var reader = await dataReader;
var dbColumns = await reader.GetColumnSchemaAsync();
T t = default;
if (await reader.ReadAsync())
{
var func = dbColumns.CreateFastSetValue<T>();
t = func.Invoke(reader);
}
await reader.FinalProcessingAsync();
return t;
} /// <summary>
/// 列表构建
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dataReader">数据读取</param>
/// <returns></returns>
public static List<T> ListBuild<T>(this DbDataReader dataReader)
{
var reader = dataReader;
var dbColumns = reader.GetColumnSchema();
var list = new List<T>();
var func = dbColumns.CreateFastSetValue<T>();
while (reader.Read())
{
list.Add(func.Invoke(reader));
}
reader.FinalProcessing();
return list;
} /// <summary>
/// 列表构建异步
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dataReader">数据读取</param>
/// <returns></returns>
public static async Task<List<T>> ListBuildAsync<T>(this Task<DbDataReader> dataReader)
{
var reader = await dataReader;
var dbColumns = await reader.GetColumnSchemaAsync();
var list = new List<T>();
var func = dbColumns.CreateFastSetValue<T>();
while (await reader.ReadAsync())
{
list.Add(func.Invoke(reader));
}
await reader.FinalProcessingAsync();
return list;
} /// <summary>
/// 字典构建
/// </summary>
/// <param name="dataReader">数据读取</param>
/// <returns></returns>
public static Dictionary<string, object> DictionaryBuild(this DbDataReader dataReader)
{
var reader = dataReader;
var data = new Dictionary<string, object>();
var dbColumns = reader.GetColumnSchema();
if (dbColumns.Count > 0 && reader.Read())
{
data = new Dictionary<string, object>();
foreach (var c in dbColumns)
{
data.Add(c.ColumnName, reader.IsDBNull(c.ColumnOrdinal.Value) ? null : reader.GetValue(c.ColumnOrdinal.Value));
}
}
reader.FinalProcessing();
return data;
} /// <summary>
/// 字典构建异步
/// </summary>
/// <param name="dataReader">数据读取</param>
/// <returns></returns>
public static async Task<Dictionary<string, object>> DictionaryBuildAsync(this Task<DbDataReader> dataReader)
{
var reader = await dataReader;
var data = new Dictionary<string, object>();
var dbColumns = await reader.GetColumnSchemaAsync();
if (dbColumns.Count > 0 && await reader.ReadAsync())
{
data = new Dictionary<string, object>();
foreach (var c in dbColumns)
{
data.Add(c.ColumnName, reader.IsDBNull(c.ColumnOrdinal.Value) ? null : reader.GetValue(c.ColumnOrdinal.Value));
}
}
await reader.FinalProcessingAsync();
return data;
} /// <summary>
/// 字典列表构建
/// </summary>
/// <param name="dataReader">数据读取</param>
/// <returns></returns>
public static List<Dictionary<string, object>> DictionaryListBuild(this DbDataReader dataReader)
{
var reader = dataReader;
var data = new List<Dictionary<string, object>>();
var dbColumns = reader.GetColumnSchema();
if (dbColumns.Count > 0)
{
while (reader.Read())
{
var keyValues = new Dictionary<string, object>();
foreach (var c in dbColumns)
{
keyValues.Add(c.ColumnName, reader.IsDBNull(c.ColumnOrdinal.Value) ? null : reader.GetValue(c.ColumnOrdinal.Value));
}
data.Add(keyValues);
}
}
reader.FinalProcessing();
return data;
} /// <summary>
/// 字典列表构建异步
/// </summary>
/// <param name="dataReader">数据读取</param>
/// <returns></returns>
public static async Task<List<Dictionary<string, object>>> DictionaryListBuildAsync(this Task<DbDataReader> dataReader)
{
var reader = await dataReader;
var data = new List<Dictionary<string, object>>();
var dbColumns = await reader.GetColumnSchemaAsync();
if (dbColumns.Count > 0)
{
while (await reader.ReadAsync())
{
var keyValues = new Dictionary<string, object>();
foreach (var c in dbColumns)
{
keyValues.Add(c.ColumnName, reader.IsDBNull(c.ColumnOrdinal.Value) ? null : reader.GetValue(c.ColumnOrdinal.Value));
}
data.Add(keyValues);
}
}
await reader.FinalProcessingAsync();
return data;
}
}
}

Emit 实体绑定源码开源,支持类以及匿名类绑定(原创)的更多相关文章

  1. 【转】TCP/UDP简易通信框架源码,支持轻松管理多个TCP服务端(客户端)、UDP客户端

    [转]TCP/UDP简易通信框架源码,支持轻松管理多个TCP服务端(客户端).UDP客户端 目录 说明 TCP/UDP通信主要结构 管理多个Socket的解决方案 框架中TCP部分的使用 框架中UDP ...

  2. 日志组件Log2Net的介绍和使用(附源码开源地址)

    Log2Net是一个用于收集日志到数据库或文件的组件,支持.NET和.NetCore平台. 此组件自动收集系统的运行日志(服务器运行情况.在线人数等).异常日志.程序员还可以添加自定义日志. 该组件支 ...

  3. Netty 源码 Channel(二)核心类

    Netty 源码 Channel(二)核心类 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) 一.Channel 类图 二. ...

  4. Netty 源码 Channel(二)主要类

    Netty 源码 Channel(二)主要类 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) 一.Channel 类图 二. ...

  5. JUC源码分析-集合篇:并发类容器介绍

    JUC源码分析-集合篇:并发类容器介绍 同步类容器是 线程安全 的,如 Vector.HashTable 等容器的同步功能都是由 Collections.synchronizedMap 等工厂方法去创 ...

  6. Jsoup解析网页源码时常用的Element(s)类

    Jsoup解析网页源码时常用的Element(s)类 一.简介 该类是Node的直接子类,同样实现了可克隆接口.类声明:public class Element extends Node 它表示由一个 ...

  7. C# 网络斗地主源码开源

    C# 网络斗地主源码开源多线程 讨论交流及  下载地址 可以发送聊天消息

  8. android:“新版飞机大战”源码开源啦!

    今天10.24,为了纪念程序猿的节日,把之前写过的一个"飞机大战"的一个源码开源了. 源码地址:https://github.com/nuptboyzhb/newplanegame ...

  9. 1、Spark 2.1 源码编译支持CDH

    目前CDH支持的spark版本都是1.x, 如果想要使用spark 2x的版本, 只能编译spark源码生成支持CDH的版本. 一.准备工作 找一台Linux主机, 由于spark源码编译会下载很多的 ...

  10. THINKPHP_(8)_修改TP源码,支持基于多层关联的任一字段进行排序

    之前博文 前述博文THINKPHP_(1)_修改TP源码,支持对中文字符串按拼音进行排序,其解决的主要问题是,对于查询出的think\collection数据,按指定字段对数据进行排序,从而在页面上进 ...

随机推荐

  1. PostgreSQL 12 文档: 部分 II. SQL 语言

    部分 II. SQL 语言 这部份描述在PostgreSQL中SQL语言的使用.我们从描述SQL的一般语法开始,然后解释如何创建保存数据的结构.如何填充数据库以及如何查询它.中间的部分列出了在SQL命 ...

  2. NodeJS使用npm安装vue脚手架

    开发环境准备:Windows10.Windows11 NodeJS,安装官网最新LTS版即可 下载地址:https://nodejs.org/安装一路下一步,默认即可 ================ ...

  3. 10/29/2017_C语言_三道题

    1. 用标准C编程:找出整形数字1-100之间的素数,并打印出来.(素数:除了1和自己本身可以被整除.) 2. 用标准C编程:有两个整形变量m.n,求出这两个数的最小公倍数. 3. 用标准C编程:输出 ...

  4. Tomcat改jar

    Tomcat改jar 插件修改 <!-- <plugin>--> <!-- <groupId>org.apache.maven.plugins</gro ...

  5. Mysql生成测试数据函数

    1.查看设置是否允许创建函数系统参数 show variables like 'log_bin_trust_function_creators'; 2.临时设置允许创建函数系统参数 set globa ...

  6. Java与PHP的区别

    1.PHP暂时不支持像Java那样的JIT运行时编译的热点代码,但PHP具有opcache机制,能够将脚本对应的opcode缓存在内存中. 补充:JIT与JVM的三种执行模式:解释模式.编译模式.混合 ...

  7. [kvm]硬盘IO优化

    硬盘类型选择 在CentOS7中有IDE.SATA和virtio三种,建议用virtio三种.virtio是半虚拟化的,性能媲美原生. 缓存模式选择 缓存模式有五种,不过常用的只有三种:writeth ...

  8. 部署安装zookeeper集群

    版本:3.7.0 节点IP: 172.50.13.103 172.50.13.104 172.50.13.105 获取安装包: wget http://mirrors.ustc.edu.cn/apac ...

  9. jmeter对请求响应结果进行整段内容提取方法

    通过正则表达式提取器,将上一个请求(A请求)响应数据中的整段内容提取,传给下一个需要该提取数据的请求(B请求). 1. 请求接口响应结果 2. 添加正则表达式提取器 设置变量名为"tt&qu ...

  10. ModuleNotFoundError: No module named 'requests' 解决办法

    问题记录:运行python程序时,出现报错:ModuleNotFoundError: No module named 'requests' 问题原因:没有安装requests库 解决办法:安装requ ...