Yuebon.NetCore/Yuebon.Commons/Helpers/EntityMapper.cs

(开头部分) 7KB

这里只显示每个文件的开头 60 行。登录后可以解锁完整代码。

using System.Collections.Concurrent;
using System.Data;
using System.Data.Common;
using System.Reflection;
using System.Reflection.Emit;

namespace Yuebon.Commons.Helpers
{
    /// <summary>
    /// 实体类映射,源自SqlSugar(http://www.codeisbug.com/Doc/3/1113)
    /// </summary>
    public static class EntityMapper
    {
        private delegate T MapEntity<T>(DbDataReader dr);

        //把DataRow转换为对象的委托声明
        private delegate T Load<T>(DataRow dataRecord);

        //用于构造Emit的DataRow中获取字段的方法信息
        private static readonly MethodInfo getValueMethod = typeof(DataRow).GetMethod("get_Item", new Type[] { typeof(int) });

        //用于构造Emit的DataRow中判断是否为空行的方法信息
        private static readonly MethodInfo isDBNullMethod = typeof(DataRow).GetMethod("IsNull", new Type[] { typeof(int) });


        private static readonly ConcurrentDictionary<Type, Delegate> CachedMappers = new ConcurrentDictionary<Type, Delegate>();

        public static IEnumerable<T> ToList<T>(this DbDataReader dr)
        {
            // If a mapping function from dr -> T does not exist, create and cache one
            if (!CachedMappers.ContainsKey(typeof(T)))
            {
                // Our method will take in a single parameter, a DbDataReader
                Type[] methodArgs = { typeof(DbDataReader) };

                // The MapDR method will map a DbDataReader row to an instance of type T
                DynamicMethod dm = new DynamicMethod("MapDR", typeof(T), methodArgs,
                    Assembly.GetExecutingAssembly().GetType().Module);
                ILGenerator il = dm.GetILGenerator();

                // We'll have a single local variable, the instance of T we're mapping
                il.DeclareLocal(typeof(T));

                // Create a new instance of T and save it as variable 0
                il.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes));
                il.Emit(OpCodes.Stloc_0);

                foreach (PropertyInfo pi in typeof(T).GetProperties())
                {
                    // Load the T instance, SqlDataReader parameter and the field name onto the stack
                    il.Emit(OpCodes.Ldloc_0);
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldstr, pi.Name);

                    // Push the column value onto the stack
                    il.Emit(OpCodes.Callvirt, typeof(DbDataReader).GetMethod("get_Item", new Type[] { typeof(string) }));

                    // Depending on the type of the property, convert the datareader column value to the type
                    switch (pi.PropertyType.Name)
                    {
后面还有 115 行代码,解锁后查看完整代码

24 小时内免费解锁 3 个项目,之后 1 算力/个。 规则说明

AI 解读 AI

登录后可用,每次 10 算力,解读结果公开显示在下面。

还没有人解读过这个文件。