PredicateBuilder is still true even after adding explicit false statement - c#

I have the following statement.
var search = PredicateBuilder.True<SomeType>();
search.And(f => false);
// Still the "search" variable value is: {f => true}.
At first, I was trying an expression; nothing succeeded, so I tried this "false" instead. No matter what I did, it's still the same. What is happening?

PredicateBuilder methods don't mutate the expression (they couldn't, as expression trees are immutable) - you need to use the return value:
var search = PredicateBuilder.True<SomeType>();
search = search.And(f => false);

Related

get delegate does not take 1 argument error when using linq

i am trying to add the statement after i form the linq statement. However, i get this error after i verified the code is correct. Why it cause the error?
query3 = query3.Where(a => a.product_group_id.Contains(1));
i added the using System.Linq.Dynamic; on the top.
Try:
var query3 = query3.Where(a => a.product_group_id == 1).Select(i=>i).ToList();
.Where() returns IEnumerable. You can't mix Contains with Where, since the first returns bool, not int.
Try .Any() if you want to check if db has the element with specified condition.
bool query3 = query3.Any(a => a.product_group_id == 1);
.Contains() returns bool. It only check if the OBJECT exists.
bool query3 = query3.Contains(yourProduct);

How can I use a Lambda bool method within a WHERE clause?

I have a method IsMatchingRegex which will return true or false. I want to check whether the Lambda property matches against the IsMatchingRegEx. If it does match, it should be added to the validItems List. How can I make the Lambda Expression work without changing the TRUE/FALSE method?
validItems = items.Where(x => x.Sub.PropertyToCheck == IsMatchingRegex(x.Sub.PropertyToCheck))
Why compare equality to the property? Just:
validItems = items.Where(x => IsMatchingRegex(x.Sub.PropertyToCheck));
The Where expects a predicate that given an item of the collection returns for it true or false. If you method already does that - just call it.

Rewriting a Linq statement

Here is what I currently have:
from s in domainThreads.Values
where (s.IsAvailable)
select s;
but I'm still learning Linq and believe that I can get it all on one line. Does the following look correct?
domainThreads.Values.Where(s => s.IsAvailable).Any();
Do I need the .Any()?
Any() returns a boolean indicating whether or not there are any entities in the given set.
The equivalent of your original LINQ expression would simply be:
domainThreads.Values.Where(s => s.IsAvailable)
The two are not equivalent.
The first returns all Values where s.IsAvailable.
The second returns whether there are any such values.
A correct conversion is:
domainThreads.Values.Where(s => s.IsAvailable)
Which translates to:
domainThreads.Values.Where(s => s.IsAvailable).Select(s => s)
Which is what the original query gets transformed to anyways.
You don't need the Any() -- that will return a bool indicating if any of elements satisfy the condition.
Instead, just do:
domainThreads.Values.Where(s => s.IsAvailable)
domainThreads.Values.Where(s => s.IsAvailable)
is enough.
Any() returns a bool value, but your original query returns a data set. So just use Where()
var result = domainThreads.Values.Where(s => s.IsAvailable);
Any() would be helpful when you just need ensure that at least single item satisfies a condition
Try this
var obj = domainThreads.Values.Where(s => s.IsAvailable == true).Select(o => o);
If you call Any() it returns bool which indicates that you have at least one item.
domainThreads.Values.Where(s => s.IsAvailable);
this expression is enough and it is equivalent to the LINQ statement.
Any() returns a boolean that is true if the result contains one or more items.
var elements = from s in domainThreads.Values
where (s.IsAvailable)
select s;
//elements now contains a list of objects.
This is equivalent to:
elements = domainThreads.Where(s => s.IsAvailable);
It looks but is not the same. The result is boolean and returns true if the collection contains any elements.
You could write something like this, but is it really worth the effort?
var result = domainThreads.Values.Where(s => s.IsAvailable).Select(s => s);
or shorter:
var result = domainThreads.Values.Where(s => s.IsAvailable);
EDIT: if you just want to have one line of code you can also write:
from s in domainThreads.Values where s.IsAvailable select s;
It's much more readable and generates to the same code in the end.

Alternative to Contains method in Generics

I use C# Asp.net 4 and Linq.
I have a Generics of type BOOL.
I need to check if at least an element in the Generics is TRUE.
At the moment I'm using the Contains method (all is working fine).
List<bool> userIsValid = new List<bool>();
userIsValid.Add(false);
userIsValid.Add(true);
userIsValid.Add(false);
if (userIsValid.Contains(true))
// do smt here
I would like to know if exist another approach without using the Contains method.
Many Thanks!
You can use Any():
if(userIsValid.Any(b => b)) { ... }
This will return true as soon as it hits a true condition specified by the lambda. In this case as the values in your list are booleans it simply needs to check the value. A more verbose way of writing it would be .Any(b => b == true) but this is unnecessary.
You could do this:
if (userIsValid.Aggregate((x,y) => x || y)) { ... }
I wouldn't do this because it is not very clear code, and it is actually slower than the other options because it won't return as soon as it finds a true.
But if you are just looking for esoteric solutions...
These would work:
Exists()
userIsValid.Exists(true);
or
Any()
userIsValid.Any(x => x);

Linq expression that would always return true

I need to pass a parameter to a method that requires an Expression<Func<T, bool>>.
How to do I pass an expression that would always return true?
Using obj => true doesn't work because the framework complains at runtime that it cannot determine the memeber type from the True constant.
If you have a function like this
void TakeExpression<T>(Expression<Func<T, bool>> expr)
You should call it this way, specifying the T type :
TakeExpression<int>(_ => true)
It should work.
You need to define the parameter type you are passing:
(object o) => true
Or
(int a) => true
We can achieve the result as follows.
Consider context as your DbContext instance and Entity as your entity class name.
context.Entity.Where(t=> t.EntityID == t.EntityID);
By doing this the where clause will always return true and all the data will be shown.
There are two problems here:
1) If you're passing a predicate such that you always want to return true, then it's not much of a predicate. You may be able to omit whatever call you are trying to make.
2) If you want to just return true, you can simple use a more verbose lambda syntax to get what you want:
sample.AsQueryable().Where((x) => { return true; });
The more verbose syntax allows you to specify closer to an anonymous function while still being an expression.

Categories

Resources