Reputation: 3964
I am trying to put a conditional expression with in a lambda query as below
GetPeers(bool? isConnected = true)
{
dbContext
.peers
.Where(m => isConnected.HasValue ? m.IsConnected == isConnected.Value : true)
.ToList();
}
Above statement gives me Nullable object must have a value.
exception.
I dont get it! What is wrong in my query?
What I want if isConnected
is null, then it should be returning all the records otherwise on the basis of m.IsConnected == isConnected.Value
,
Upvotes: 2
Views: 2081
Reputation: 53958
You can change this
m.IsConnected == isConnected.Value
to this
m.IsConnected == (isConnected.HasValue && isConnected.Value)
The problem is that isConnected
doesn't have always a value. It's a bool?
. So it can has a value or not (null
). If it has a value, it would be either true/false. The problem arises, when it has no value. This is happening due to conditional operator. According to the documentation:
The conditional operator (?:) returns one of two values depending on the value of a Boolean expression. Following is the syntax for the conditional operator.
condition ? first_expression : second_expression;
Either the type of first_expression and second_expression must be the same, or an implicit conversion must exist from one type to the other.
For the full documentation, please have a look here.
Upvotes: 3
Reputation: 19426
This is an issue with how Entity Framework is translating the ternary expression, it is attempting to create a SQL parameter using the result of isConnected.Value
but isConnected
is null so it throws.
My preferred option is to only apply the predicate if there is actually a predicate to apply:
IQueryable<Peer> peers = dbContext.peers;
if(isConnected.HasValue)
{
var isConnectedValue = isConnected.Value;
peers = peers.Where(m => m.IsConnected == isConnectedValue);
}
return peers.ToList();
Upvotes: 4