See https://stackoverflow.com/questions/41810306/appointment-scheduling....
There are two problems with your code.
The first is how you are declaring your method:
Func<T, bool> ComposeFilter
When you do that, you are returning a compiled delegate, and the Where extension method overload that gets chosen is from Enumerable instead of Queryable.
You have to declare it as:
Expression<Func<T, bool>> ComposeFilter
The second problem is that the code you wrote cannot be converted to an expression tree. Since you are not using primitives but constructing the expression dynamically, you need to learn about the stuff in System.Linq.Expressions.
Related
Related To: Create a Lambda Expression With 3 conditions
Please consider this GroupBy statement:
group r by new { r.EmployeeID, r.Name }
If I want to write above GroupBy statement with Lambda version and pass Expression<Func<T, TKey>> to it as parameter, How I can create Expression<Func<T, TKey>>?
I don't have time to walk you through the whole thing, but the general gist is that you'll construct expressions using static methods off of the Expression class.
For example, the new expression will be created by passing constructor information and a series of expressions and such to one of the Expression.New() overloads.
The concept of r => ... is embodied by Expression.Lambda<Func<T, TKey>>(...) where you pass an Expression.Parameter(typeof(T), "r") as the lambda's parameter.
Expression.MakeMemberAccess will help you to produce r.EmployeeId and r.Name.
I find it useful to start by dumping a sample expression in LINQPad with code like this:
void Main()
{
DumpExp(r => new { r.EmployeeID, r.Name });
}
public void DumpExp<TKey>(Expression<Func<Foo, TKey>> expr)
{
expr.Dump();
}
public class Foo
{
public string EmployeeID;
public string Name;
}
That will allow you to inspect the tree and understand what types of expressions make up the tree, and what the values of their properties are. Then you can try writing code to match.
Once you've got an Expression that you think will work, you can call Compile on it to produce a runnable function, which you can use to test its behavior on in-memory objects.
I'm guessing the anonymous type you've got there may be the most difficult part of the problem. If the target framework supports something like Tuples in its GroupBy statements, you will probably be better off using those instead.
There is an oldish project that was designed to enable you to run dynamic LINQ statements built by providing strings to LINQ-like methods. It's called "Dynamic LINQ", and it might suit your needs.
You might also find this library useful. It's supposed to help you build Expression trees with a more fluent syntax. However, it doesn't appear to be under active development.
I have a Lazy<T> initialized with a lambda. How to see the body of the initializing lambda while debugging? I expect to have something like the DebugView of the Expression class but I've found nothing like that.
Because Lazy<T> takes a delegate, there is no Expression class involved. Your lambda is compiled like any other code in your project and there is no preview of that code during debug.
Lambda expression can be compiled either into IL or transformed into Expression Tree. Which one happens depends on the context. If your parameter is declared as delegate regular IL code will be generated. If it's Expression<TFunc> you'll get expression tree which can be previewed.
It's nicely explained on MSDN, based on Where method, which has two versions: Enumerable.Where which takes Func<T, bool> and Queryable.Where which takes Expression<Func<T, bool>>.
When you use method-based syntax to call the Where method in the
Enumerable class (as you do in LINQ to Objects and LINQ to XML) the
parameter is a delegate type System.Func<T, TResult>. A lambda
expression is the most convenient way to create that delegate. When
you call the same method in, for example, the System.Linq.Queryable
class (as you do in LINQ to SQL) then the parameter type is an
System.Linq.Expressions.Expression<Func> where Func is any of the Func
delegates with up to sixteen input parameters. Again, a lambda
expression is just a very concise way to construct that expression
tree. The lambdas allow the Where calls to look similar although in
fact the type of object created from the lambda is different.
I have some questions / concerns using LINQ in my projects. First question is - Is there is difference in performance between old (select Item from..) linq and new version (.Select(r => ..))?
Second question, How LINQ expresions is being translated (and in what)? Will it be translated to old syntax first and then to something else (intermediate language)?
There isn't any difference between the two ways we can write a linq query.
Specifically, this
var adults = from customer in customers
where customer.Age>18
select customer;
is equivalent to this:
var adults = customers.Where(customer=>customer.Age>18);
Actually, the compiler translates the first query to the second query. The first way of writing a linq query is something like a syntactic sugar. Under the hood, if you compile your code and then you make use of a dissasembler to see the IL code, you will notice that your query has been translated to the second one of the above forms.
Queries written with the first way, we say that we have used the query syntax. While queries written with the second way, we say that we have used the fluent syntax.
Is there is difference in performance between old (select Item from..) linq and new version (.Select(r => ..))?
Neither of these are older than the other, as both came into the language with at the same time. If anything .Select() could be argued as older as while the method call will almost always be a call to an extension method (and hence only available since .NET 3.5 and only callable that way with C# 3.0) there were method calls generally since 1.0.
There's no difference in performance, as they are different ways to say the same thing. (It's just about possible that you could find a case that resulted in a redundancy for one but not the other, but for the most part those redundancies are caught by the compiler and removed).
How LINQ expresions is being translated (and in what)? Will it be translated to old syntax first and then to something else (intermediate language)?
Consider that, as per the above, from item in someSource select item.ID and someSouce.Select(item => item.ID) are the same thing. The compiler has to do two things:
Determine how the call should be made.
Determine how the lambda should be used in that.
These two go hand in hand. The first part is the same as with any other method call:
Look for a method defined on the type of someSource that is called Select() and takes one parameter of the appropriate type (I'll come to "appropriate type" in a minute).
If no method is found, look for a method defined on the immediate base of the type of someSource, and so on until you have no more base classes to examine (after reaching object).
If no method is found, look for an extension method defined on a static class that is available to use through a using which has its first (this) parameter the type of someSource, and its second parameter of the appropriate type that I said I'll come back to in a minute.
If no method is found, look for a generic extension method that can accept the types of someSource and the lambda as parameters.
If no method is found, do the above two steps for the base types of someSource and interfaces it implements, continuing to further base types or interfaces those interfaces extend.
If no method is found, raise a compiler error. Likewise, if any of the above steps found two or more equally applicable method in the same step raise a compiler error.
So far this is the same as how "".IsNormalized() calls the IsNormalized() method defined on string, "".GetHashCode() calls the GetHashCode() method defined on object (though a later step means the override defined on string is what is actually executed) and "".GetType() calls the GetType() method defined on object.
Indeed we can see this in the following:
public class WeirdSelect
{
public int Select<T>(Func<WeirdSelect, T> ignored)
{
Console.WriteLine("Select Was Called");
return 2;
}
}
void Main()
{
int result = from whatever in new WeirdSelect() select whatever;
}
Here because WeirdSelect has its own applicable Select method, that is executed instead of one of the extension methods defined in Enumerable and Queryable.
Now, I hand-waved over "parameter of the appropriate type" above because the one complication that lambdas bring into this is that a lambda in C# code can be turned into either a delegate (in this case a Func<TSource, TResult> where TSource is the type of the lambdas parameter and TResult the type of the value it returns) or an expression (in this case a Expression<Func<TSource, TResult>>) in the produced CIL code.
As such, the method call resolution is looking for either a method that will accept a Func<TSource, TResult> (or a similar delegate) or one that will accept an Expression<Func<TSource, TResult>> (or a similar expression). If it finds both at the same stage in the search there will be a compiler error, hence the following will not work:
public class WeirdSelect
{
public int Select<T>(Func<WeirdSelect, T> ignored)
{
Console.WriteLine("Select Was Called");
return 2;
}
public int Select<T>(Expression<Func<WeirdSelect, T>> ignored)
{
Console.WriteLine("Select Was Called on expression");
return 1;
}
}
void Main()
{
int result = from whatever in new WeirdSelect() select whatever;
}
Now, 99.999% of the time we are either using select with something that implements IQueryable<T> or something that implements IEnumerable<T>. If it implements IQueryable<T> then the method call resolution will find public static IQueryable<TResult> Select<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector) defined in Queryable and if it implements IEnumerable<T> it will find public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector) defined in Enumerable. It doesn't matter that IQueryable<T> derives from IEnumerable<T> because its method will be found in an earlier step in the process described above, before IEnumerable<T> is considered as a base interface.
Therefore 99.999% of the time there will be a call made to one of those two extension methods. In the IQueryable<T> case the lambda is turned into some code that produces an appropriate Expression which is then passed to the method (the query engine then able to turn that into whatever code is appropriate, e.g. creating appropriate SQL queries if its a database-backed query engine, or something else otherwise). In the IEnumerable<T> case the lamda is turned into an anonymous delegate which is passed to the method which works a bit like:
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
{
//Simplifying a few things, this code is to show the idea only
foreach(var item in source)
yield return selector(item);
}
To come back to your question:
Will it be translated to old syntax first and then to something else (intermediate language)?
You could think of the newer from item in source select… syntax as being "turned into" the older source.Select(…) syntax (but not really older since it depends on extension methods over 99% of the time) because it makes the method call a bit clearer, but really they amount to the same thing. In the CIL produced the differences depend on whether the call was a instance method or (as is almost always the case) an extension method and even more so on whether the lambda is used to produce an expression or a delegate.
I have the following code;
IQueryable<MyClass> query = listOfObjects.Where(x => x.SomeProp == 1);
I pass this to a method on a particular API that is expecting an IQueryable, which is fine.
However, I want to dynamically build up the predicate, so I'm using Expression.Lambda to achieve this, and I then .Compile it to turn it back into a Func<MyObject, bool>.
I would have expected that the following would have worked;
Func<MyClass, bool> predicate = x => GetPredicate();
IQueryable<MyClass> query = list.Fields.Where(predicate);
However, passing predicate to Where has changed the return type to IEnumerable<MyClass>, which isn't the type required by the API obviously.
I did (naively) try predicate.AsQueryable(), but the API in question (SharePoint Client Object model) just fails with a generic "Specified method is not supported." error message.
I don't know if this a limitation of the LINQ provider that is behind the scenes, but regardless... I'm keen to understand why pulling the Func out into its own variable and passing it in to Where affects the type inference in the way it does.
IQueryable is using an expression tree to build predicate. So, instead of
Func<MyClass, bool> predicate = x => GetPredicate();
use:
Expression<Func<MyClass, bool>> predicate = x => GetPredicate();
Keep in mind:
While using IQueryable expression tree is built (tree that represents operation (as operands and arguments) made on collection). In order to translate tree into other form (let's say sql query, depends on LINQ proider) translator must know all operands used in to tree. It looks like that translator in service where you are passing IQueryable don't know what does GetPredicate function do (and don't know how to translate it to sql query) so throws Not Supported Exception..
The same thing is with Func instead of Expression. Func is complied version of predicate (stored as delegate) - provider don't know how to translate delegates. When Expression is used, the predicate is stored as tree, so provider can "look inside" an expression and translate it correctly.
I'm wondering what exactly is the difference between wrapping a delegate inside Expression<> and not ?
I'm seeing Expression<Foo> being used a lot with LinQ, but so far I've not found any article that explains the difference between this, and just using a delegate.
E.g.
Func<int, bool> Is42 = (value) => value == 42;
vs.
Expression<Func<int, bool>> Is42 = (value) => value == 42;
tl;dr, To have an expression is like having the source code of an application, and a delegate is an executable to run the application. An expression can be thought of as the "source" (i.e., syntax tree) of the code that would run. A delegate is a specific compilation that you would run and does the thing.
By storing a lambda as a delegate, you are storing a specific instance of a delegate that does some action. It can't be modified, you just call it. Once you have your delegate, you have limited options in inspecting what it does and whatnot.
By storing a lambda as an expression, you are storing an expression tree that represents the delegate. It can be manipulated to do other things like changing its parameters, changing the body and make it do something radically different. It could even be compiled back to a delegate so you may call it if you wish. You can easily inspect the expression to see what its parameters are, what it does and how it does it. This is something that a query provider can use to understand and translate an expression to another language (such as write an SQL query for a corresponding expression tree).
It is also a whole lot easier to create a delegate dynamically using expressions than it is emitting the code. You can think of your code at a higher level as expressions that is very similar to how a compiler views code instead of going low-level and view your code as IL instructions.
So with an expression, you are capable to do much more than a simple anonymous delegate. Though it's not really free, performance will take a hit if you run compiled expressions compared to a regular method or an anonymous delegate. But that might not be an issue as the other benefits to using expressions may be important to you.
Func<> is just a delegate type. An Expression is a runtime representation of the complete tree of operations which, optionally, may be compiled at runtime into a delegate. It's this tree that is parsed by Expression parsers like Linq-to-SQL to generate SQL statements or do other clever things. When you assign a lambda to an Expression type, the compiler generates this expression tree as well as the usual IL code. More on expression trees.
To illustrate other answers, if you compile those 2 expressions and have look at the compiler generated code, this i what you will see:
Func<int, bool> Is42 = (value) => value == 42;
Func<int, bool> Is42 = new Func<int, bool>((#value) => value == 42);
Expression<Func<int, bool>> Is42 = (value) => value == 42;
ParameterExpression[] parameterExpressionArray;
ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "value");
Expression<Func<int, bool>> Is42 = Expression.Lambda<Func<int, bool>>(Expression.Equal(parameterExpression, Expression.Constant(42, typeof(int))), new ParameterExpression[] { parameterExpression });
Expression Trees allow you to inspect the code inside the expression, in your code.
For example, if you passed this expression: o => o.Name, your code could find out that the Name property was being accessed inside the expression.
Provides the base class from which the classes that represent
expression tree nodes are derived.
System.Linq.Expressions.BinaryExpression
System.Linq.Expressions.BlockExpression
System.Linq.Expressions.ConditionalExpression
System.Linq.Expressions.ConstantExpression
System.Linq.Expressions.DebugInfoExpression
System.Linq.Expressions.DefaultExpression
System.Linq.Expressions.DynamicExpression
System.Linq.Expressions.GotoExpression
System.Linq.Expressions.IndexExpression
System.Linq.Expressions.InvocationExpression
System.Linq.Expressions.LabelExpression
System.Linq.Expressions.LambdaExpression
System.Linq.Expressions.ListInitExpression
System.Linq.Expressions.LoopExpression
System.Linq.Expressions.MemberExpression
System.Linq.Expressions.MemberInitExpression
System.Linq.Expressions.MethodCallExpression
System.Linq.Expressions.NewArrayExpression
System.Linq.Expressions.NewExpression
System.Linq.Expressions.ParameterExpression
System.Linq.Expressions.RuntimeVariablesExpression
System.Linq.Expressions.SwitchExpression
System.Linq.Expressions.TryExpression
System.Linq.Expressions.TypeBinaryExpression
System.Linq.Expressions.UnaryExpression
http://msdn.microsoft.com/en-us/library/system.linq.expressions.expression.aspx
Expression tree represents linq expression that can be analyzed and for example turned into SQL query.
To whatever the other wrote (that is completely correct) I'll add that through the Expression class you can create new methods at runtime. There are some limits. Not all the things you can do in C# can be done in an Expression tree (at least in .NET 3.5 . With .NET 4.0 they have added a great number of possible Expression "types"). The use of this could be (for example) to create a dynamic query and pass it to LINQ-to-SQL or do some filtering based on the input of the user... (you could always do this with CodeDom if all you wanted was a dynamic method incompatible with LINQ-to-SQL, but emitting directly IL code is quite difficult :-) )