The best you can do is capture the predicate in an Expression<>
. A method has already been compiled to IL and so isn't able to be picked apart by a Linq provider.
Expression<Func<DamageList, bool>> predicate = item => item.DamageCount > 5;
You can then pass that predicate directly to Where
:
var q = session.Linq<DamageList>().Where(predicate);
If you want to dynamically combine two such expressions, you either write the code for both into the one expression, or you capture both in separate expressions. This gets complicated because you need each one to refer to an item
being passed in. This is really a different question, already asked: How do I dynamically create an Expression<Func<MyClass, bool>> predicate?
You can write a compound predicate using the && oerator and still capture it in an expression:
Expression<Func<DamageList, bool>> predicate =
dl => dl.DamageCount > 5 && dl.Name.Contains(criteria);
You ask about calling methods in such an expression - well, that example does call a method!
It builds a tree of Expression
nodes of various types. Included somewhere will be a method call node, which says to call the Contains
method of string
(assuming Name
is a string
). So this is an example of a method call instruction embedded in an expression. In order for this to work, the Linq provider has to know what that method does, so it can turn it into the equivalent SQL (as would be the case for a typical ORM system).
So you can embed certain standard method calls in expressions - it requires the Linq provider to know about them. The methods of string
are well defined, but not every provider will necessarily be able to deal with all of them.
It wouldn't be impossible for a Linq provider to allow you to add your own extensions that handle extra methods, but I'm not aware of any that support that (obviously if the system is open source, you can add your own).
To summarise - a Linq provider needs a tree of expression nodes that it can analyse to convert into some other language such as SQL, for execution in another context such as inside a remote database. If you write ordinary methods, the C# compiler will compile them into low-level executable IL, not expression nodes. So that is like a dead-end: there's no built-in facility for turning IL back into expression nodes.