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); }
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); }