Why Would You Use Expression≪Func≪T≫≫ Rather Than Func≪T≫

Why would you use ExpressionFuncT rather than FuncT?

When you want to treat lambda expressions as expression trees and look inside them instead of executing them. For example, LINQ to SQL gets the expression and converts it to the equivalent SQL statement and submits it to server (rather than executing the lambda).

Conceptually, Expression<Func<T>> is completely different from Func<T>. Func<T> denotes a delegate which is pretty much a pointer to a method and Expression<Func<T>> denotes a tree data structure for a lambda expression. This tree structure describes what a lambda expression does rather than doing the actual thing. It basically holds data about the composition of expressions, variables, method calls, ... (for example it holds information such as this lambda is some constant + some parameter). You can use this description to convert it to an actual method (with Expression.Compile) or do other stuff (like the LINQ to SQL example) with it. The act of treating lambdas as anonymous methods and expression trees is purely a compile time thing.

Func<int> myFunc = () => 10; // similar to: int myAnonMethod() { return 10; }

will effectively compile to an IL method that gets nothing and returns 10.

Expression<Func<int>> myExpression = () => 10;

will be converted to a data structure that describes an expression that gets no parameters and returns the value 10:

Expression vs Func larger image

While they both look the same at compile time, what the compiler generates is totally different.

Difference between ExpressionFunc and Func

Using Expression<T> you are explicitly creating an expression tree - this means that you can deal with the code that makes up the query as if it were data.

The reason for this is that LINQ providers (like LINQ to SQL for example) inspect the query itself to determine the best way to translate the C# expressions into a T-SQL query. Since an expression tree lets you look at the code as data the provider is able to do this.

ExpressionFuncT,bool vs FuncT,bool in method overloading

The expression that the compiler is complaining about is the argument to "CallTo" method:

A.CallTo(() => mandrill.SendMessageTemplate(A<SendMessageTemplateRequest>.That.Matches(...)));

So it doesn't matter which overload of Matches is chosen.

ExpressionFuncT, Boolean VS FuncT, Boolean

Using Expression vs Func really depends on your use case and which Linq provider you are using.

If you are using Entity Framework, Linq to SQL, or any other query provider that translates expression trees into some other query language then you have to use Expression.

If you are using Linq to Objects, then you have a choice. Usually you would want to use Func directly, without first creating an expression then compiling it.

You might use Expression if what you are doing requires building arbitrary and complex queries at runtime. In this case you would call compile before executing the query. The common example of this would users providing complex search queries through a UI.

diffrence between running query with Func and Expression Func

my question is,we usualy should use the expression func when we deal with DB?

Yes, because you want to give as much information to the SQL server so that it can optimize the database access and you want to minimize the data that is returned from the SQL Server (removing all the unnecessary data, and aggregating the data that can be easily aggregated by the SQL Server) because moving data from the SQL Server to the .NET machine is even that a "work".

Clearly if something is very difficult to do in SQL (like string manipulation), then moving it to .NET is acceptable.

Note that with LINQ you don't have fine control on the resulting query, that can easily become a "multi-level-beast", nor you can be really sure which part of the query will be executed on the SQL server and which part will be executed locally (EF Core for example often executes GROUP BY locally), nor can access many advanced features of SQL (all the partitioning methods for example).

Convert ExpressionActionT to ExpressionFuncT

It's simple, just create a new Expression<Func<MyExecutor, int>> using the body and parameters from the existing expression:

static Expression<Func<MyExecutor, int>> ToExpressionOfFunc(Expression<Action<MyExecutor>> expr)
{
return Expression.Lambda<Func<MyExecutor, int>>(expr.Body, expr.Parameters);
}

Note that this throws an exception if expr is not of return type int.

ExpressionFuncT parameter causes calling code to use Expression.Lambda

If you would look at the decompiled code of your caller, you would see something like the following:

 public void SetPropertyX(MyTypedDataRow dataRow, string value)
{
var parameter = Expression.Parameter("x", typeof(MyTypedDataRow));
dataRow.Set(Expression.Lambda<Func<MyTypedDataRow, string>>(Expression.Property(parameter, "PropertyX"), parameter) , value);
}

As you can see your lambda is constructed inline.

Unfortunately for a method that is called a lot, this has a really big performance impact. In this case either save the expression tree (e.g x=>x.PropertyX) to a static field, or if there is too many of them, then cache them by property name ( and if you have a limited amount of columntypes, then also by column types)

How to convert LambdaExpression to ExpressionFuncT,bool in C#

The ExpressionHelper.GetLambda<T, bool> method used to obtain the lambda expression hides its actual type, which is the desired Expression<Func<T, bool>>, so all you need is to use a cast operator:

return (Expression<Func<T, bool>>)lambdaExpression;

Or better, either change the result type of ExpressionHelper.GetLambda<TSource, TDest> to Expression<Func<TSource, TDest>>, or don't use that helper method - when you know the generic type arguments at compile time, simply use one if the generic Expression.Lambda methods (ExpressionHelper.GetLambda<TSource, TDest> seems to be the equivalent of Expression.Lambda<Func<TSource, TDest>>), e.g.

var lambdaExpression = Expression.Lambda<Func<T, bool>>(parameterExpression, finalExpression);

How to merge two ExpressionFuncT, T

Because you never use Func argument you can simplify your code and use Func<T>. Next method will merge two (or more) MemberInitExpression into one:

public static Expression<Func<T>> MergeExpressions<T>(params Expression<Func<T>>[] expressions)
where T : new()
{
var allBindings = new List<MemberBinding>();
foreach (var expression in expressions)
{
var bindings = ((MemberInitExpression) expression.Body).Bindings;
allBindings.AddRange(bindings);
}

var body = Expression.MemberInit(Expression.New(typeof(T)), allBindings);
return Expression.Lambda<Func<T>>(body);
}

You can check it online here



Related Topics



Leave a reply



Submit