Skip to content

Instantly share code, notes, and snippets.

@jasondentler
Created April 23, 2014 16:28
Show Gist options
  • Save jasondentler/11222385 to your computer and use it in GitHub Desktop.
Save jasondentler/11222385 to your computer and use it in GitHub Desktop.
Convert DataRow to POCO
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace Reporting
{
public static class ReflectionExtensions
{
public static TInstanceType Convert<TInstanceType>(this DataRow row) where TInstanceType : new()
{
var retval = new TInstanceType();
foreach (var propName in SetterDelegateCache<TInstanceType>.WritablePropertyNames)
{
var value = row.IsNull(propName) ? null : row[propName];
SetterDelegateCache<TInstanceType>.Write(propName, retval, value);
}
return retval;
}
private static class SetterDelegateCache<TInstanceType>
{
private static readonly Dictionary<string, Action<TInstanceType, object>> Setters;
static SetterDelegateCache()
{
Setters = typeof (TInstanceType)
.GetProperties()
.Where(p => p.CanWrite)
.ToDictionary(pi => pi.Name, BuildSetDelegate<TInstanceType>);
}
public static IEnumerable<string> WritablePropertyNames
{
get { return Setters.Keys; }
}
public static void Write(string propertyName, TInstanceType instance, object value)
{
Setters[propertyName](instance, value);
}
}
private static Action<TInstanceType, object> BuildSetDelegate<TInstanceType>(PropertyInfo pi)
{
var instanceParam = Expression.Parameter(typeof(TInstanceType), "row");
var valueParam = Expression.Parameter(typeof(object), "value");
var convert = Expression.Convert(valueParam, pi.PropertyType);
var property = Expression.Property(instanceParam, pi);
var assign = Expression.Assign(property, convert);
var lambda = Expression.Lambda<Action<TInstanceType, object>>(assign, instanceParam, valueParam);
return lambda.Compile();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment