A strange thing about Nullable Boolean type, And and Or in C#

I have a strange problem about the following codes:

!isActive.HasValue || (isActive.HasValue && x.IsActive == isActive.Value)

isActive is a bool? type, so if isActive is null, then I will get the following error:

Nullable object must have a value.

Any idea about that? Thanks for your help!

Update 1:

public static List<User> Select(int userId, bool? isActive = null)
{
    var dl = DataLayer.GetDataContext();
    return dl.Users.Where(x => x.ID == userId
                && (!isActive.HasValue || (isActive.HasValue && x.IsActive == isActive.Value))).ToList();
}

This is the sample function I got this error. I know it is so strange! If I change like below, it will work:

!isActive.HasValue || (isActive.HasValue && x.IsActive == isActive)

I understand this error mean, but I don't understand why. It should work I think. So I call it strange thing!

Update 2:

  1. x.IsActive is bool type, not bool?. I am sure on it :)
  2. DataLayer.GetDataContext() is for Linq to SQL.

Is it possible it is because I am using SQL Server?

Thanks guys for your help so far.

Answers


Since it's Linq-to-SQL, then perhaps it's not short-circuiting or evaluating the expression parts in the proper order. I haven't used it, but from what I understand it reads the content of your lambda expressions and converts it to a close equivalent SQL statement; it does not actually execute it like C# code.

Even so, doing the check for each item seems like a bit much when the value is fixed. You could rewrite the method as such:

public static List<User> Select(int userId, bool? isActive = null)
{
    var dl = DataLayer.GetDataContext();
    var users = dl.Users.Where(x => x.ID == userID);

    if (!isActive.HasValue)
    {
        return users.ToList();
    }
    else
    {
        bool isActiveValue = isActive.Value;
        return users.Where(x => x.IsActive == isActiveValue).ToList();
    }
}

This way there's no additional constraints on the generated SQL query if they're not applicable. EDIT: Updated it so in addition, there are no nullable booleans being passed into your query whatsoever.


You have two different isActive values in your code, so it looks like you're missing the x on the second check:

!isActive.HasValue || (x.isActive.HasValue && (x.IsActive == isActive.Value))
                   ----^

I've also added parentheses around the equality check just to eliminate any confusion around the order or operations


Oh, it's because of the query builder in LINQ. There may be a way to execute your intention in one query (in fact it sounds like your updated code in the q does just that), but the straightforward thing to do is to split it into two queries since you know the value of isActive beforehand. That way you don't have to worry about what the query builder may or may not be doing.

For that matter you may as well just make this two separate functions entirely, just to make it harder for future maintainers to accidentally fall into the same trap:

public static List<User> Select(int userId)
{
    return DataLayer.GetDataContext().Users.Where(x => x.ID == userId).ToList();
}

public static List<User> Select(int userId, bool isActive)
{
    return DataLayer.GetDataContext().Users.Where(x => x.ID == userId && x.IsActive == isActive).ToList();
}

Need Your Help

Trigger.io: File Access - Getting total Counts of Images in my Gallery (iPhone/Android)

android iphone file camera trigger.io

Is there any way to get the total counts of Pictures in my Gallery? We need to preview the total counts in my gallery. We can't find what API method to be used for it.

JavaScript error: NS_ERROR_XPC_BAD_CONVERT_JS

javascript dom

I am getting this JavaScript error, doing some research people are saying something about instantiating an object.

Are there any reasons not to use “this” (“Self”, “Me”, …)?

programming-languages multiple-languages

I read this answer and its comments and I'm curious: Are there any reasons for not using this / Self / Me ?