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:
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
Possible to Call C++ Code from C#
How to Convert HTML to Plain Text
Difference Between a Field and a Property
How to Implement Custom Jsonconverter in Json.Net
Why Saving Changes to a Database Fails
How to Get a Consistent Byte Representation of Strings in C# Without Manually Specifying an Encoding
Difference Between I++ and ++I
How to Recursively List All the Files in a Directory in C#
Using Cookiecontainer With Webclient Class
How to Translate Between Windows and Iana Time Zones
Entity Framework Code First - Two Foreign Keys from Same Table
JavaScriptserializer - Json Serialization of Enum as String
The Provider Is Not Compatible With the Version of Oracle Client
Filesystemwatcher Changed Event Is Raised Twice
How to Get the Index of the Current Iteration of a Foreach Loop