What's the purpose of adding compiled Func methods together? - c#

I have seen that is is possible to add compiled methods together.
Expression<Func<Customer, bool>> ln = c => c.lastname.Equals(_customer.lastName, StringComparison.InvariantCultureIgnoreCase);
Expression<Func<Customer, bool>> fn = c => c.firstname.Equals(_customer.firstName, StringComparison.InvariantCultureIgnoreCase);
Expression<Func<Customer, bool>> fdob = c => c.DOB.ToString("yyyyMMdd").Equals(_customer.DOB.ToString("yyyyMMdd"));
var filter = ln.Compile() + fn.Compile() + fdob.Compile();
Does it make sense to do this?
I would intend to use the filter in place of a lambda expression to filter a repository of customers:
IEnumerable<Customer> customersFound = _repo.Customers.Where(filter);
Depending on business logic, I may or may not add the three compiled methods together, but pick and choose, and possibly add more compiled methods as I go.
Can anyone explain if adding them together would build up a query string or not? Anyone got a better suggestion?
I could chain "Where" statements and use regular lambda expressions, but I am intrigued by what you might gain from compiling methods and adding them up!

That's a side-effect of the fact that the Compile method returns a delegate.
Internally, a delegate is a multicast-delegate, it can involve multiple chained references to methods.
The + is in this case just a quick way to chain them together. You can read more about combining delegates in the How to: Combine Delegates on MSDN.
Here's a LINQPad program that demonstrates:
void Main()
{
var filter = GetX() + GetY() + GetZ();
filter().Dump();
}
public int X() { Debug.WriteLine("X()"); return 1; }
public int Y() { Debug.WriteLine("Y()"); return 2; }
public int Z() { Debug.WriteLine("Z()"); return 3; }
public Func<int> GetX() { return X; }
public Func<int> GetY() { return Y; }
public Func<int> GetZ() { return Z; }
Output:
X()
Y()
Z()
3
Note that it thus seems to just disregard the return value from the first method calls, and returns only the last, although it fully calls the prior methods as well.
Note that the above code is similar to this:
void Main()
{
Func<int> x = X;
Func<int> y = Y;
Func<int> z = Z;
var filter = x + y + z;
filter().Dump();
}
public int X() { Debug.WriteLine("X()"); return 1; }
public int Y() { Debug.WriteLine("Y()"); return 2; }
public int Z() { Debug.WriteLine("Z()"); return 3; }
The short answer is thus that no, this does not do what you want it to do.

When you call Compile(), you are creating instances of type Func<Customer, bool>, which is a delegate.
Delegates overload the operator+ to return Multicast Delegates, which is what is happening here.
See MSDN: How to: Combine Delegates (Multicast Delegates)
So, no - adding them together would not build up a query string.
If this is for EF, you want to use Expression Trees, not Lambdas.
You can create and modify Expression Trees using the System.Linq.Expressions namespace:
MSDN: System.Linq.Expressions Namespace
and
MSDN: How to: Use Expression Trees to Build Dynamic Queries

It is a creative effort to chain predicates and too bad it does not work. The reason why has been explained excellently by Lasse and Nicholas (+2). But you also ask:
Anyone got a better suggestion?
The drawback of compiled expressions is that they're not expressions any more and thus, can't be used with IQueryables that are backed by SQL query providers (like linq to sql or linq to entities). I assume _repo.Customers is such an IQueryable.
If you want to chain expressions dynamically, LINQKit's PredicateBuilder is an excellent tool to do this.
var pred = Predicate.True<Customer>();
pred = pred.And(c => c.lastname.Equals(_customer.lastName, StringComparison.InvariantCultureIgnoreCase);
pred = pred.And(c => c.firstname.Equals(_customer.firstName, StringComparison.InvariantCultureIgnoreCase);
pred = pred.And(c => c.DOB.ToString("yyyyMMdd").Equals(_customer.DOB.ToString("yyyyMMdd"));
var customersFound = _repo.Customers.Where(pred.Expand());
This is what the Expand is for:
Entity Framework's query processing pipeline cannot handle invocation expressions, which is why you need to call AsExpandable on the first object in the query. By calling AsExpandable, you activate LINQKit's expression visitor class which substitutes invocation expressions with simpler constructs that Entity Framework can understand.
Or: without it an expression is Invoked, which causes an exception in EF:
The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.
BTW. If you use linq to sql/entities you may as well use c.lastname == _customer.lastName because it is translated into SQL and the database collation will determine case sensitiveness.

Related

I'm confused about this statement. Lambda operator? [duplicate]

This question already has answers here:
Understanding how lambda expression works [closed]
(4 answers)
Closed 3 years ago.
[Route("{year:min(2000)}/{month:range(1,12)}/{key}")]
public IActionResult Post(int year, int month, string key)
{
var post = _db.Posts.FirstOrDefault(x => x.Key == key);
return View(post);
}
Hi,
I'm doing this in ASP.NET Core with C#.
Vague part for me is this: _db.Posts.FirstOrDefault(x => x.Key == key);
So what I'm guessing is that:
execute FirstOrDefault method.
parameter x is passed (I don't what it is being passed exactly though).
then, compare x.Key with key
what is next step?
parameter x is passed (I don't what it is being passed exactly though).
No, this does not happen. What is passed is an expression defining an anonymous function. Such expressions, when using the => operator, are commonly called lambda expressions. x is the part of the expression which determines how the function is called. It's a placeholder for the input variable used by the function expression.
It will help you understand if I give you a pretend version of how the FirstOrDefault() method might be implemented:
public T FirstOrDefault<T>(this IEnumerable<T> items, Func<T, boolean> predicate)
{
foreach(T item in items)
{
if(predicate(item)) return item;
}
return default(T);
}
Some things to understand in that code:
this in front of the first parameter turns the function into an extension method. Instead of calling the method with two arguments, you skip the first argument... call it with only the second argument as if it were a member of the type from the first argument. ie, _db.Posts.FirstOrDefault(foo) instead of FirstOrDefault(_db.Posts, foo).
The key variable in the expression is called a closure. It is available as part of the predicate() function inside this method, even though it's not passed as an argument. This is why the predicate(item) call is able to determine true or false with only item as an input.
The predicate() function call within this method was passed as an argument to the method. That is how the x => x.Key == key argument is interpreted; it becomes the predicate() method used by the FirstOrDefault() function. You can think of it as if predicate() were defined like this:
bool predicate(T x)
{
return x.Key == key;
}
The C# compiler makes this translation for you automatically, and even infers the correct run-time type for T and automatically handles scope for the key closure.
The other answers are close, but not completely correct.
I assume that _db is an Entity Framework DbContext, and _db.Posts is a DbSet<Post>.
As such the .FirstOrDefault() method you are seeing is actually an Extension method and the x => x.Key == key part is an Expression tree.
What happens behind the scenes is that the call to _db.Posts.FirstOrDefault(x => x.Key == key) is translated to a SQL statement like SELECT TOP(1) Key, Content, ... FROM posts WHERE Key = #key, the result of which is mapped into a Post entity.
There are a lot of language features at play to make all this work, so let's have a look!
Extension methods
Extension methods are static methods, but can be called like instance methods.
They are defined in static classes and have a 'receiver' argument. In the case of FirstOrDefault the extension method looks like this:
public static class Queryable {
public static T FirstOrDefault<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate = null) {
// do something with source and predicate and return something as a result
}
}
It's usage _db.Posts.FirstOrDefault(...) is actually syntactic sugar and will be translated by the C# compiler to a static method call a la Queryable.FirstOrDefault(_db.Posts, ...).
Note that extension methods are, despite the syntactic sugar, still static methods do not have have access to their receiver's internal state. They can only access public members.
Delegates
C# has support for pseudo-first-class functions, called delegates. There are several ways to instantiate a delegate.
They can be used to capture existing methods or they can be initialized with an anonymous function.
The most elegant way to initialize a delegate with an anonymous function is to use lambda style functions like x => x + 10 or (x, y) => x + y.
The reason you don't see type annotations in these examples is that the compiler can infer the types of the arguments in many common situations.
Here is another example:
// This is a normal function
bool IsEven(int x) {
return x % 2 == 0;
}
// This is an anonymous function captured in a delegate of type `Func<T1, TResult>`
Func<int, bool> isEven = x => x % 2 == 0;
// You can also capture methods in delegates
Func<int, bool> isEven = IsEven;
// Methods can be called
int a = IsEven(5); // result is false
// Delegates can be called as well
int b = isEven(4); // result is true
// The power of delegates comes from being able to pass them around as arguments
List<int> Filter(IEnumerable<int> array, Func<int, bool> predicate) {
var result = new List<int>();
foreach (var n in array) {
if (predicate(n)) {
result.Add(n);
}
}
return result;
}
var numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
var evenNumbers = Filter(numbers, isEven); // result is a list of { 2, 4, 6 }
var numbersGt4 = Filter(numbers, x => x > 4); // result is a list of { 5, 6 }
Expression trees
The C# compiler has a feature that allows you to create an Expression tree with normal-looking code.
For example Expression<Func<int, int>> add10Expr = (x => x + 10); will initialize add10Expr not with an actual function but with an expression tree, which is an object graph.
Initialized by hand it would look like this:
Expression xParameter = Expression.Parameter(typeof(int), "x");
Expression<Func<int, int>> add10Expr =
Expression.Lambda<Func<int, int>>(
Expression.Add(
xParameter,
Expression.Constant(10)
),
xParameter
);
(which is super cumbersome)
The power of expression trees comes from being able to create, inspect and transform them at runtime.
Which is what Entity Framework does: it translates these C# expression trees to SQL code.
Entity Framework
With all of these features together you can write predicates and other code in C# which gets translated by Entity Framework to SQL, the results of which are "materialized" as normal C# objects.
You can write complex queries to the database all within the comfort of C#.
And best of all, your code is statically typed.
The x is the range variable of the object you called the function on. The same object you would get in foreach (var x in _db.Posts) It then iterates through that collection looking for x.Key == key and returns the first object that fulfills that. So that function will return the first object in db.Posts where Key == key
edit: corrected term
Your lambda expression with FirstOrDefault is equivalent to the following extension method
public static Post FirstOrDefault(this YourDBType _db, string Key)
{
foreach(Post x in _db.Posts)
{
if(x.Key == Key)
{
return x
}
}
return null
}
X isn't an parameter, its just a shorthand way of referring to the individual item in the collection you are working on like we would have in a foreach statement. The last step in your question is "either return the first Post that has the same key we are comparing against, or return the default value of a Post object (which is null for objects)"

How to create a delegate from Expression<Func< , >>? (pass a parameter to the expression)?

I have the following filter :
Expression<Func<Employee, bool>> fromDateFilterFourDays = z => EntityFunctions.TruncateTime(z.FiringDate) >= EntityFunctions.TruncateTime(DateTime.Now.AddDays(-4));
Expression<Func<Employee, bool>> fromDateFilterSixDays = z => EntityFunctions.TruncateTime(z.FiringDate) >= EntityFunctions.TruncateTime(DateTime.Now.AddDays(-6));
How can I make a delegate out of this filter ?
I don't want to create a variable for each given number , i.e. for four days or six days .
My understanding is that you want to:
Take in two parameters to the delegate, the employee and the number of days.
Compile that expression into a delegate.
The first part can be done by adding the days to the parameter list:
Expression<Func<Employee, int, bool>> fromDateFilter = (z, n) => EntityFunctions.TruncateTime(z.FiringDate) >= EntityFunctions.TruncateTime(DateTime.Now.AddDays(n));
The second by using the Compile method:
var del = fromDateFilter.Compile();
// use it
del(employee, -4);
You can easily turn Expression<Func<...>> to Func<...> by using Compile method.
However, keep in mind that the sample expressions you provided will not work, because they are using Canonical Functions which are just placeholders for mapping the corresponding database SQL functions, and will throw exception if you try to actually evaluate them (which will happen with Func).
From the other side, if the question is actually how to parametrize the sample expressions, it could be like this
static Expression<Func<Employee, bool>> DateFilter(int currentDateOffset)
{
return e => EntityFunctions.TruncateTime(e.FiringDate) >= DateTime.Today.AddDays(currentDateOffset);
}
This is done by calling the Invoke() method:
fromDateFilterFourDays.Invoke(employee);
Or you can Compile() the expression to a func and then call the func:
var fromDateFilterFourDaysFunc = fromDateFilterFourDays.Compile();
fromDateFilterFourDaysFunc(employee);

Convert Method to Linq Expression for query

In our application we want to have standard methods for various conditions in our database. For instance, we have different types of transactions, and we want to create standard methods for retrieving them within other queries. However, this gives us the error:
Method '' has no supported translation to SQL
The method might look like this:
public static bool IsDividend(this TransactionLog tl)
{
return tl.SourceTypeID == (int)JobType.Dividend || tl.SourceTypeID == (int)JobType.DividendAcct;
}
To be used as such:
var dividends = ctx.TransactionLogs.Where(x => x.IsDividend());
Of course, if I copy the logic from IsDividend() into the Where clause, this works fine, but I end up duplicating this logic many places and is hard to track down if that logic changes.
I think if I would convert this to an expression like this it would work, but this is not as preferable a setup as being able to use methods:
public Expression<Func<TransactionLog, bool>> IsDividend = tl => tl.SourceTypeID == (int)JobType.Dividend || tl.SourceTypeID == (int)JobType.DividendAcct;
var dividends = ctx.TransactionLogs.Where(IsDividend);
Is there a way to force Linq to evaluate the method as an expression? Or to "transform" the method call into an expression within a linq query? Something like this:
var dividends = ctx.TransactionLogs.Where(tl => ToExpression(tl.IsDividend));
We are using Linq-to-SQL in our application.
Well having static property containing the expressions seems fine to me.
The only way to make it work with Methods would be to create a method which returns this expression, and then call it inside where:
public class TransactionLog
{
Expression<Func<TransactionLog, bool>> IsDividend() {
Expression<Func<TransactionLog, bool>> expression = tl => tl.SourceTypeID == (int)JobType.Dividend || tl.SourceTypeID == (int)JobType.DividendAcct;
return expression;
}
}
public class TransactionLogExtension
{
Expression<Func<TransactionLog, bool>> IsDividend(this TransactionLog log) {
Expression<Func<TransactionLog, bool>> expression = tl => tl.SourceTypeID == (int)JobType.Dividend || tl.SourceTypeID == (int)JobType.DividendAcct;
return expression;
}
}
and use it via
var dividends = ctx.TransactionLogs.Where(TransactionLog.IsDividend());
or as extension method
var dividends = ctx.TransactionLogs.Where(x.IsDividend());
But none of it is will work with var dividends = ctx.TransactionLogs.Where(x => x.IsDividend()); because x => x.IsDividend(); itself is an expression tree and your database provider can't translate "IsDividend" into an SQL statement.
But the other two options will at least allow you to pass in parameters (which doesn't work if you store the Expressions as instance or static properties).
I think that LINQ to SQL doesn't fully supports even common and build-in functions. (At least EF does not do it). And moreover - when it deals with user defined methods. I predict that your variant with expression will fall as well as the variant with method call unless you call it after enumeration (ToList or similar method). I suggest to keep the balance between 1) stored procedures at server, 2) common conditions hardcoded in Where clauses in C#, 3) expression trees generation in C#. All these points are relatively complex, for sure (and to my mind there is no easy and general solution).
Try using Extension Methods, like so:
public static class TransactionLogExtensions {
public static IQueryable<TransactionLog> OnlyDividends(this IQueryable<TransactionLog> tl)
{
return tl.Where(t=>t.SourceTypeID == (int)JobType.Dividend || t.SourceTypeID == (int)JobType.DividendAcct);
}
}
Call it like so:
var dividends=db.TransactionLogs.OnlyDividends();
or
var dividends=db.TransactionLogs.OnlyDividends().OrderBy(...);
For this scenario you can use Func. Linq works very good with those.
Here is the simple example of using Func in Linq query. Feel free to modify and use.
Func<int,bool> isDivident = x => 3==x;
int[] values = { 3, 7, 10 };
var result = values.Select (isDivident );

Convert a Func<T> to Expression<Func<T>> for a known T [duplicate]

Since we can:
Expression<Func<int, bool>> predicate = x => x > 5;
var result = Enumerable.Range(0,10).Where(predicate.Compile());
How can I:
Func<int,bool> predicate = x => x > 5;
Expression<Func<int,bool>> exp = predicate.Decompile();
That is, I want to get the corresponding Expression of the Func. Is it possible?
There is no magic Decompile() for a delegate instance, short of deconstructing the IL (perhaps with mono.cecil). If you want an expression tree, you'll have to start with an expression tree, so have Expression<Func<int, bool>> througout.
As an edge case, you can get basic method delegate information from the delegate's .Method (the MethodInfo) and .Target (the arg0) - however, for most scenarios involving a lambda or anonymous method this will point at the compiler-generate method on the capture class, so won't really help you much. It is pretty much limited to scenarios like:
Func<string,int> parse = int.Parse;
Pass the lambda to a method that accepts an Expression<> and the C# compiler will pass you an expression tree at runtime. However this only works if you pass the lambda directly, not if you try to pass a delegate instance created from a lambda.
var exp = Decompile(x => x > 5);
public Expression<Func<int, bool>> Decompile(Expression<Func<int, bool>> exp)
{
return exp;
}
The closest option I've found for decompiling a delegate instance is detailed in this blog post from Jean-Baptiste Evain who works on the Mono team. He uses the excellent Mono.Cecil project to decompile the IL into a custom AST, then he maps it as best as possible into LINQ expressions.
You can try to use my library:
https://github.com/ashmind/expressive
Though it may not work as is for results of Compile(), since it is a DynamicMethod and getting IL of it is not straightforward. If you implement your own IManagedMethod implementation for DynamicMethod, though, it should just work.
I plan to implement DynamicMethod adapters, but do not yet know when.
You can’t decompile the delegate, but you can certainly create a new expression tree that simply calls the delegate:
Func<int, bool> predicate = x => x > 5;
Expression<Func<int, bool>> exp = x => predicate(x);

Lambda expression syntax

Is it mandatory that lambda expression need to use when LINQ will be used, or are lambda expressions optional?
In lambda expressions, the sign => is always used. What does it mean?
customers.Where(c => c.City == "London");
Here c => is used but why?
What kind of meaning of using c =>. Please discuss in detail because I don't know lambda.
No, you don't have to use a lambda expression. For example, your Where example could be written as:
private static bool IsLondon(Customer customer)
{
return customer.City == "London";
}
...
var londoners = customers.Where(IsLondon);
That's assuming LINQ to Objects, of course. For LINQ to SQL etc, you'd need to build an expression tree.
As to why "=>" is always used in a lambda expression, that's simply because that's the way the operator is written - it's like asking why "+" is used for addition.
A lambda expression of "c => ..." is effectively giving the lambda expression a parameter called c... in this case generic type inference provides the type of c. The body provides either an action to perform or some calculation to return a value based on c.
A full-blown description of lambda expressions is beyond the scope of this answer. As a blatant plug for my book, however, they're covered in detail in chapter 9 of C# in Depth.
The lambda expression
c => c.City == "London"
is shorthand for something like
bool IsCustomerInLondon(Customer c)
{
return (c.City == "London");
}
It's just a very concise way of writing a simple function that returns a value. It's called an "anonymous function" because it's never assigned a name or a formal definition (the parameter types and the return type are inferred from the context).
(Actually, it's not just shorthand; lambda expressions are related to some other constructs called closures, which are very cool and powerful tools.)
Think about lambdas as anonymous of functions.
I'll try to explain it with following code.
public bool IsLondon(Customer customer)
{
return customer.City == "London";
}
Now we strip down function name and get rid of braces:
public bool Customer customer
return customer.City == "London";
We don't need return type, because compiler is able to deduce type from expression:
customer.City == "London";
In the same manner compiler knows about input type, so we don't need to specify it.
So basically, what we left with is
customer
return customer.City == "London";
And lambda syntax in c# is basically:
(parameter list) => "expression"
You can also write "multi-line" expressions, but then you have to surround your code with curly braces. Also you will need to use "return" statement, like you usually do.
Jon already answered,
but I'd like to add this.
In the example you have given, imagine Linq looping over all customers,
and c is simply a reference to each item in the enumerable:
var result = new List<Customer>();
foreach(var c in customers)
{
if (c.City == "London")
result.Add(c);
}
return result;
It's a variable like any other, it does not have to be a single named one,
but it's just a convention of some sort.
you do not need to use lambda expressions on Lİnq to sql or Entities; here is an alternative way of your code;
you code :
customers.Where(c => c.City == "London");
the other way;
var query = from cs in customers
where cs.City == "London"
select cs;
this is the another way. it is up to you.
Lambda and linq are quite separate. You can use one without using the other (there are parts of linq that depend on lambda expressions, but we want to keep it simple :-) )
A lambda expression is an anonymous
function that can contain expressions
and statements, and can be used to
create delegates or expression tree
types.
This was from MSDN. (http://msdn.microsoft.com/en-us/library/bb397687.aspx )
To make it short (it's much more complex) you can use a lambda expression to make a local function. what you put before the => (in your example the c) will be the parameter of the function. The return type is "discovered" by the C# compiler.
c => c.City == "London" is nearly equivalent to:
delegate (TheObjectTypeOfC c) {
return c.City == London
};
(the difference is that some lambda expression are delegates and also expressions, but please ignore this, you won't need it for some time)
If/when the compiler isn't able to infer the types of the parameters, you can force them: (MyObject p) => p.SomeProperty != null. Here you are telling the compiler that p is a parameter.
While here I showed you what are called "expression lambdas", you can even do "statement lambdas":
p => {
for (int i = 0; i < 10; i++) {
if (p.SomeProperty == 0) {
return true;
}
}
return false;
}
(I won't tell you what are the "behind the scenes" differences between expression lambdas and statement lambdas. If you want to know them, read the msdn page I pointed before)
No it is not necessary at all.
We have two ways to write LINQ queries.
One is query method and other is builder method. You only need to put lambda expression in case of builder method.
For example, if we want to find all those students from some Students object that have more marks than 70.
but we can do this thing in LINQ with following syntax
var data = from p in stdList
where p.marks > 70
select p;
or
var data = stdList.Where(p=>p.marks > 70);
later approach is builder method, in Where function, we are passing lambda expressions.
Lambda expressions are just short cuts of doing things you can always use LINQ queries but if you want to avoid whole query syntax for just applying a simple condition you can just use LINQ builder methods (which asks for lambda expressions) in lambda expressions, you always define some alias and then perform your operation.
As far as => operator is concerned, It works just like assignment operator.
For example:
(p) => p.Gender == “F”
It means “All persons p, such that person’s Gender is F”
In some literature this is called “predicate”. Another literature terminology is “Projection”
(p) => p.Gender ? “F” : “Female”
“Each person p becomes string “Female” if Gender is “F””
This is projection, it uses ternary operator.
Although i explained with very basic examples but i hope this would help you . . . :)

Categories