c# - List of Expression<Func<T, TProperty>> -
i'm searching way store collection of expression<func<t, tproperty>>
used order elements, , execute stored list against iqueryable<t>
object (the underlying provider entity framework).
for example, (this pseudo code):
public class program { public static void main(string[] args) { orderclause<user> orderbys = new orderclause<user>(); orderbys.addorderby(u => u.firstname); orderbys.addorderby(u => u.lastname); orderbys.addorderby(u => u.age); repository<user> userrepository = new repository<user>(); ienumerable<user> result = userrepository.query(orderbys.orderbyclauses); } }
an order clause (property on order):
public class orderclause<t> { public void addorderby<tproperty>(expression<func<t, tproperty>> orderbyselector) { _list.add(orderbyselector); } public ienumerable<expression<func<t, ???>>> orderbyclauses { { return _list; } } }
a repository query method:
public class repository<t> { public ienumerable<t> query(ienumerable<orderclause<t>> clauses) { foreach (orderclause<t, ???> clause in clauses) { _query = _query.orderby(clause); } return _query.tolist(); } }
my first idea convert expression<func<t, tproperty>>
string (the property name on sort). basically, instead of storing typed list (which not possible because tproperty not constant), store list of string properties sort on.
but doesn't work because cannot reconstruct expression
(i need because iqueryable.orderby takes expression<func<t, tkey>>
parameter).
i tried dynamically create expression (with of expression.convert), have expression<func<t, object>>
got exception entity framework said not able handle expression.convert statement.
if possible, not want use external library dynamic linq library.
this 1 of few cases dynamic
/ reflection solution may appropriate.
i think want this? (i've read between lines , made changes structure thought necessary).
public class orderclauselist<t> { private readonly list<lambdaexpression> _list = new list<lambdaexpression>(); public void addorderby<tproperty>(expression<func<t, tproperty>> orderbyselector) { _list.add(orderbyselector); } public ienumerable<lambdaexpression> orderbyclauses { { return _list; } } } public class repository<t> { private iqueryable<t> _source = ... // don't know how works public ienumerable<t> query(orderclause<t> clauselist) { // needs validation, e.g. null-reference or empty clause-list. var clauses = clauselist.orderbyclauses; iorderedqueryable<t> result = queryable.orderby(_source, (dynamic)clauses.first()); foreach (var clause in clauses.skip(1)) { result = queryable.thenby(result, (dynamic)clause); } return result.tolist(); } }
the key trick getting c# dynamic
horrible overload resolution , type-inference us. what's more, believe above, despite use of dynamic
, type-safe!
Comments
Post a Comment