I am executing a lengthy LINQ query on my EF-mapped DB entity classes that is treated by Linq2Sql and ends up with an anonymous type:
...
.Where(e => ...)
.Join(..., (outer, inner) => new {
outer.Object1,
outer.TempId,
Object2 = inner
})
So far, so good - up to that point, everything will nicely be translated to SQL and run on the DB. I can iterate over the anonymously typed objects, at which point only the very data contained therein will be materialized on the C# side.
However: I now need to perform one last filtering step that will reduce the data set, which is why it should run on the DB, as well. I need to compare a property on Object1
and Object2
.
The name of this property is passed in to my method as a string.
Under normal circumstances, this wouldn't be a problem. I could simply access the anonymous object via reflection - even if it means I have to get the anonymous type by means of .GetType().GetGenericArguments()[0]
on my enumerable.
However, I need to make sure everything's typesafe here, so the ensuing foreach
will let me iterate over and work with instances of the anonymous type. Therefore, creating a filter expression is not straightforward as I cannot specify a type for Lambda<TDelegate>
- it would have to be a Func<..., Boolean>
, where ...
is my anonymous type!
I have thought about creating a project function instead that takes an instance of the type that Object1
and Object2
in my anonymous type belong to - say, ObjectData
, - and returns the property value. This would, of course, be feasible:
var prm = Expression.Parameter(typeof(ObjectData), "obj");
var projectionExpr = Expression.Lambda<Func<ObjectData, int>>(Expression.Property(prm, myPropertyName), prm);
But then I'm not sure where to apply them - I'd need some kind of a "single-item select", that just projects one value to another by means of a projection expression and that will play well with EF's LINQ to Entities/SQL generation - something like (pseudocode, with an imaginary PROJECT
function) this:
.Select(info => new {
info.Object1,
info.TempId,
info.Object2,
Value1 = PROJECT(info.Object1, projectionExpr),
Value2 = PROJECT(info.Object2, projectionExpr)
})
How do I get my final filter into the story?
Aucun commentaire:
Enregistrer un commentaire