Exemplo n.º 1
0
        public async static Task <DbTable> ToDbTableAsync(IDataReaderWrapper dataReader)
        {
            DbTable dbTable = new DbTable();

            InitDbTableColumns(dataReader, dbTable);
            while (await dataReader.ReadAsync())
            {
                var dbRow = dbTable.AddRow();
                for (int i = 0; i < dataReader.FieldCount; i++)
                {
                    var colName = dataReader.GetName(i);
                    dbRow[colName] = dataReader[colName];
                }
            }
            return(dbTable);
        }
Exemplo n.º 2
0
        private Func<IDataReader, RequestContext, object> CreateParserImpl(IDataReaderWrapper dataReader, RequestContext context, Type targetType)
        {
            var statement = context.Statement;
            var resultMap = statement?.ResultMap;
            resultMap = statement?.MultipleResultMap?.Results.FirstOrDefault(m => m.Index == dataReader.ResultIndex)?.Map ?? resultMap;

            var constructorMap = resultMap?.Constructor;

            var columns = Enumerable.Range(0, dataReader.FieldCount)
                            .Select(i => new { Index = i, Name = dataReader.GetName(i) })
                            .ToDictionary((col) => col.Name);

            var dynamicMethod = new DynamicMethod("Deserialize" + Guid.NewGuid().ToString("N"), targetType, new[] { TypeUtils.DataReaderType, TypeUtils.RequestContextType }, targetType, true);
            var iLGenerator = dynamicMethod.GetILGenerator();
            iLGenerator.DeclareLocal(targetType);
            ConstructorInfo targetCtor = null;
            if (constructorMap == null)
            {
                targetCtor = targetType.GetConstructor(
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
            }
            else
            {
                var ctorArgTypes = constructorMap.Args.Select(arg => arg.ArgType).ToArray();
                targetCtor = targetType.GetConstructor(
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, ctorArgTypes, null);
                //load arg value
                foreach (var arg in constructorMap.Args)
                {
                    var col = columns[arg.Column];
                    EmitLoadColVal(iLGenerator, dataReader, col.Index, arg.TypeHandler, arg.ArgType, null);
                }
            }

            if (targetCtor == null)
                throw new SmartSqlException($"No parameterless constructor defined for the target type: \"{targetType.FullName}\"");

            iLGenerator.Emit(OpCodes.Newobj, targetCtor); // [target]
            iLGenerator.Emit(OpCodes.Stloc_0);

            foreach (var col in columns)
            {
                var colName = col.Key;
                var colIndex = col.Value.Index;
                var result = resultMap?.Properties?.FirstOrDefault(r => r.Column == colName);
                string propertyName = result != null ? result.Name : colName;
                var property = targetType.GetProperty(propertyName);
                if (property == null) { continue; }
                if (!property.CanWrite) { continue; }
                Type propertyType = property.PropertyType;
                Label isDbNullLabel = iLGenerator.DefineLabel();
                EmitLoadColVal(iLGenerator, dataReader, colIndex, result?.TypeHandler, propertyType, isDbNullLabel);
                iLGenerator.Emit(OpCodes.Call, property.SetMethod);// stack is empty
                iLGenerator.MarkLabel(isDbNullLabel);
            }

            iLGenerator.Emit(OpCodes.Ldloc_0);// stack is [rval]
            iLGenerator.Emit(OpCodes.Ret);

            var funcType = System.Linq.Expressions.Expression.GetFuncType(TypeUtils.DataReaderType, TypeUtils.RequestContextType, targetType);
            return (Func<IDataReader, RequestContext, object>)dynamicMethod.CreateDelegate(funcType);
        }