Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq expression with nullable

Looks like stupid question, but I just dont get it. My entity:

public class Page
{
    public int Id { get; set; }
    //...
    public int? ParentId { get; set; }
}

In controller:

db.Pages.First(x => x.ParentId == null);

Works as expected (returns some element). But:

int? test = null;
db.Pages.First(x => x.ParentId == test);

Throws Sequence contains no elements

What do I miss?

like image 939
Wonder Avatar asked Feb 14 '12 09:02

Wonder


3 Answers

I believe there's an oddity around nulls with some LINQ providers. Try:

var query = db.Pages.First(x => (test != null && x.ParentId == test) ||
                                (test == null && x.ParentId == null));

Alternatively, use different queries for the different situations:

var query = test == null ? db.Pages.First(x => x.ParentId == null)
                         : db.Pages.First(x => x.ParentId == test);

Basically this is because SQL treats NULL as unequal to itself, so:

WHERE X = Y

will still fail if both X and Y are null values. Using the == null part (with a literal null) forces a conversion to ISNULL or whatever the SQL equivalent is.

I agree it's a pain, and someone else may have a better workaround, but this may help you get going.

like image 170
Jon Skeet Avatar answered Nov 14 '22 05:11

Jon Skeet


You could do something like this as a workaround:

int? test = null;
if(test.HasValue) {
 db.Pages.First(x => x.ParentId == test.Value);
} else {
 db.Pages.First(x => x.ParentId == null);
}

I'm assuming since int? is actually a Nullable<int> our linq-to-entities provider isn't comparing things right.

like image 31
gideon Avatar answered Nov 14 '22 05:11

gideon


Try this (modified according to gdoron's comment. It now is exactly what gideon posted, so please accept his instead of mine):

int? test = null;
if(test.HasValue) {
    db.Pages.First(x => x.ParentId == test.Value);
} else {
    db.Pages.First(x => x.ParentId == null);
}
like image 1
Dennis Traub Avatar answered Nov 14 '22 05:11

Dennis Traub