09/28/2020
Recently I had a need to map an IDataRecord to an entity class object in C # without using reflection for performance reasons, and because I can. Here is the code for reference... First we need the method that generates a function to map the properties while handling DBNull. private static Func GenerateMapFunction(IDataReader dataReader) { if (dataReader is null) { throw new ArgumentNullException(nameof(dataReader)); } var expressions = new List(); var dataReaderParameterExpression = Expression.Parameter(typeof(IDataRecord), "o7thDR"); var targetExpression = Expression.Variable(typeof(T)); expressions.Add(Expression.Assign(targetExpression, Expression.New(targetExpression.Type))); // does int based lookup var indexerInfo = typeof(IDataRecord).GetProperty("Item", new[] { typeof(int) }); var columnNames = Enumerable.Range(0, dataReader.FieldCount) .Select(index => new { index, name = dataReader.GetName(index) }); foreach (var column in columnNames) { var property = targetExpression.Type.GetProperty( column.name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); if (property is null) { continue; } // index var columnIndexExpression = Expression.Constant(column.index); // reader[index] var readerPropertyExpression = Expression.MakeIndex( dataReaderParameterExpression, indexerInfo, new[] { columnIndexExpression }); // reader.IsDBNull(index); var isReaderDbNull = Expression.Call( dataReaderParameterExpression, nameof(IDataReader.IsDBNull), null, columnIndexExpression); // reader[index] as PropertyType; var safeCastExpression = Expression.TypeAs( readerPropertyExpression, property.PropertyType); // T.Property var targetPropertyExpression = Expression.Property(targetExpression, property); // T.Property = reader.IsDBNull(index) ? [ 402 more words ]
Recently I had a need to map an IDataRecord to an entity class object in C # without using reflection for performance reasons, and because I can. Here is the code for reference…