Skip to content

Instantly share code, notes, and snippets.

@mikezhuyuan
Created August 14, 2012 16:03
Show Gist options
  • Save mikezhuyuan/3350500 to your computer and use it in GitHub Desktop.
Save mikezhuyuan/3350500 to your computer and use it in GitHub Desktop.
var type = typeof(T);
var props = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetProperty);
var dr = Expression.Parameter(typeof(IDataReader), "dr");
var result = Expression.Parameter(typeof(List<T>), "result");
var resultAdd = typeof(List<T>).GetMethod("Add");
var drRead = typeof(IDataReader).GetMethod("Read");
var getOrdinal = typeof(IDataRecord).GetMethod("GetOrdinal");
ParameterExpression[] ords = props.Select((prop, index) => Expression.Variable(typeof(int), "ord" + index)).ToArray();
var itm = Expression.Parameter(type, "itm");
var endLoop = Expression.Label("endLoop");
Expression body =
Expression.Block(
ords.Union(new[]{ itm, result }),
Union(
Expression.Assign(result, Expression.New(typeof(List<T>))),
ords.Select((ord, index) =>
Expression.Assign(ord,
Expression.Call(dr, getOrdinal, Expression.Constant(props[index].Name))
)),
Expression.Loop(
Expression.IfThenElse(
Expression.Call(dr, drRead),
Expression.Block(
Union(
Expression.Assign(itm, Expression.New(type)),
props.Select((prop, index) => {
var name = prop.Name;
var ptype = prop.PropertyType;
var method = ObjectAssemblerHelper.GetMethod(ptype, "Ordinal");
return Expression.Assign(Expression.Property(itm, name), Expression.Call(null, method, dr, ords[index]));
}),
Expression.Call(result, resultAdd, itm))),
Expression.Break(endLoop)),
endLoop),
result));
return Expression.Lambda<Func<IDataReader, IEnumerable<T>>>(body, new[] { dr }).Compile();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment