Just save the current lambda in a temporary variable to prevent recursion var tempFunc = func; func = a => tempFunc(a) &&.
Just save the current lambda in a temporary variable to prevent recursion. Var tempFunc = func; func = a => tempFunc(a) && ...
This works, wish I'd seen it 5 mins ago. Lol. For a cleaner way, I used an extension method... – TheSoftwareJedi May 12 '09 at 18:01 That won't work for expression-based lambdas for IQueryable – Marc Gravell?
May 12 '09 at 19:04.
If you want to do an "and" combination, the preferred option is to use multiple "where" clauses: IQueryable query = ... if (!string. IsNullOrEmpty(txtName.Text. Length)) { //add it to the function query = query.
Where(a => a.Name. StartsWith(txtName. Text)); } if (!string.
IsNullOrEmpty(txtType.Text. Length)) { //add it to the function query = query. Where(a => a.
Type == txtType. Text); } You can do more complex things with expression building (AndAlso, Invoke, etc), but this is not necessary for an "and" combination. If you really need to combine expressions, then the approach depends on the implementation.
LINQ-to-SQL and LINQ-to-Objects support Expression. Invoke, allowing: static Expression> OrElse( this Expression> lhs, Expression> rhs) { var row = Expression. Parameter(typeof(T), "row"); var body = Expression.
OrElse( Expression. Invoke(lhs, row), Expression. Invoke(rhs, row)); return Expression.
Lambda>(body, row); } static Expression> AndAlso( this Expression> lhs, Expression> rhs) { var row = Expression. Parameter(typeof(T), "row"); var body = Expression. AndAlso( Expression.
Invoke(lhs, row), Expression. Invoke(rhs, row)); return Expression. Lambda>(body, row); } However, for Entity Framework you will usually need to rip the Expression apart and rebuild it, which is not easy.
Hence why it is often preferable to use Queryable. Where (for "and") and Queryable. Concat (for "or").
I am right in the middle of doing exactly this... I am using Expressions because Func is compiled code where as Expression> can be converted C# or TSql or what ever... I just have seen several people recommend using expression instead of just func. On you search page you would implement the code like this: SearchCritera crit = new SearchCriteria(); if (txtName.Text. Length > 0) { //add it to the function crit.
Add(a.Name. StartsWith(txtName. Text)); } if (txtType.Text.
Length > 0) { //add it to the function crit. Add(a. Type == txtType.
Text)); } The SearchCriteria object look something like this... public class SearchCritera { private List>> _Criteria = new List>>(); public void Add(Expression> predicate) { _Criteria. Add(predicate); } // This is where your list of Expression get built into a single Expression // to use in your Where clause public Expression> BuildWhereExpression() { Expression> result = default(Expression>); ParameterExpression parameter = Expression. Parameter(typeof(TEntity), "entity"); Expression previous = _Criteria0; for (int I = 1; I (previous, parameter); return result; } } Then from your Where clause you could do this... public List FindAllCustomers(SearchCriteria criteria) { return LinqToSqlDataContext.Customers.
Where(SearchCriteria. BuildWhereExpression()).ToList(); } This is the first time I have coded this out and you might need to make some changes for your purposes, I know it compliles but when I acutally go to do it I will unit test it, but it is the idea I have been tossing around in my head...
This gave a strange runtime error. However, I found the PredicateBuilder class (see my answer) and it works perfectly... – TheSoftwareJedi May 12 '09 at 19:00.
If you're going to be using this in LinqToSQL or any other dynamic expression tree parser, you're going to want to use PredicateBuilder! Otherwise: This extension method will prevent the recursion: public static Func And(this Func f1, Func f2) { return a => f1(a) && f2(a); } public static Func Or(this Func f1, Func f2) { return a => f1(a) || f2(a); } Use it like so: Func func == a => true; if (txtName.Text. Length > 0) { //add it to the function func.
And(a => a.Name. StartsWith(txtName. Text)); } if (txtType.Text.
Length > 0) { //add it to the function func. And(a => a. Type == txtType.
Text); }.
Dictionary, Expression>> filters = new Dictionary, Expression>>(); // add a name filter filters. Add( () => txtName.Text. Length > 0, a => a.Name.
StartsWith(txtName. Text) ); // add a type filter filters. Add( () => txtType.Text.
Length > 0, a => a. Type == txtType. Text ); ... var query = dc.Orders.AsQueryable(); foreach( var filter in filters .
Where(kvp => kvp.Key()) . Select(kvp => kvp. Value) ) { var inScopeFilter = filter; query = query.
Where(inScopeFilter); }.
Just save the current lambda in a temporary variable to prevent recursion. Query = query. Where(a => a.Name.
Query = query. Where(a => a.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.