I'd like to use expression trees to improve performance of some object-relational mapping code. The old code looks something like this:
public List<T> SqlToResults<T>(string query)
{
// Do SQL stuff, get matching constructor for type T ...
// ...
List<T> results = new List<T>();
// Create buffer for constructor parameters
object[] constructorParams = new object[reader.FieldCount];
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
// simplefied (there'd be some mapping to match correct order of parameters)
constructorParams[i] = reader[i];
}
// create new instance of T with our data
T result = (T)constructorInfoOfT.Invoke(constructorParams);
// add new result to list of results
results.Add(result);
}
return results;
}
The performance bottle neck in above code is the call to ConstructorInfo.Invoke()
which I'd like to replace with an expression tree and a call to Expression.New()
similar to the code in this answer. However at compile time I don't know the number of parameters and their types it seems to be a bit more complicated. Expression.New()
takes an array of Expressions as the argument to the constructor but I only have an array of objects (which would be a single ParameterExpression
). So I'd somehow have to loop over the content of the ParameterExpression
to then map every element to it's own Expression
which then can be passed as an Expression[]
to Expression.New()
.
The code I have in mind would look something like this:
internal delegate TInstance Constructor<TInstance>(object[] parameters);
internal Constructor<T> BuildConstructerFrom<T>(ConstructorInfo constructorInfo)
{
ParameterExpression constructorParameters = Expression.Parameter(typeof(object[]));
Expression[] parameterExpressions;
// ???
// somehow map entries in constructorParameters to entries in parameterExpressions
// ???
NewExpression constructorCall = Expression.New(constructorInfo, parameterExpressions);
Constructor<T> ctor = (Constructor<T>)Expression.Lambda<Constructor<T>>(constructorCall, constructorParameters).Compile();
return ctor;
}
I have taken a look at similar questions like foreach loop using expression trees and issue while building dynamic expression tree but I'm still unsure as to how to use these loops in my use case.
Aucun commentaire:
Enregistrer un commentaire