AKD
AKD

Reputation: 3964

Ternary operator in lambda expression C#

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

Answers (2)

Christos
Christos

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

Lukazoid
Lukazoid

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

Related Questions