Scott
Scott

Reputation: 13941

Using FirstOrDefault() in a Where() clause

I've got a LINQ query that's returning no results when I know that it should be returning at least one. I'm building up the query dynamically. I looked at the result set in the debugger right before I get to the line that filters out all of the results and it contains hundreds of rows. After this line, it contains 0 when it really should contain at least one.

query = query.Where(x => 
    x.Lineages.FirstOrDefault().Sire.Contains(options.PedigreeContains));

'x' in this case represents an entity called 'Horse'. 'options.PedigreeContains' is just a string value. The Lineages table looks like this:

ID         HorseID         Sire       Dam        etc...

I can even pull up a Horse entity in the debugger (the one I know should be returned as a result), inspect the Lineages property and see it fully populated, including the Sire value that matches my search. So everything SEEMS like it should be working, except there's obviously some issue with the LINQ query that I'm using.

Does anyone see anything inherently wrong with what I'm doing that would cause this to filter out results that I know should be there?

EDIT: For clarification, it's a 1-to-1 relationship. I know the Lineages object exists, I know there's only one, and I know it matches. It's just for some reason it's returning zero results so I thought there might be a problem with the way I wrote the query. If that query should work the way it's written though (minus all of the extra "possibilities" if no lineages exist, more than one, etc) then it must be an issue somewhere else in my code.

Upvotes: 0

Views: 3748

Answers (4)

istepaniuk
istepaniuk

Reputation: 4269

Actually answring your question: No. There is nothing inherently wrong with your query. It must be an issue somewhere else in your query construction, in the database structure or in your data.

When debugging, instead of enumerating and verifying the result count, copy the query expression value and look what the generated SQL looks like. You can do that before and after altering the IQueryable query. Other suggestions like @Jalalx use of .Any() to avoid what @John Saunders points out.

Upvotes: 1

David Culp
David Culp

Reputation: 5480

You are providing no means to order the Lineages, if the first one returned does not have the desired Sire containing option.PedigreeContains. In such a case, the result set would be empty, regardless of the other Sire's in the Lineages.

Upvotes: 1

Tim Destan
Tim Destan

Reputation: 2028

If you do FirstOrDefault() where you have it, aren't you taking the first of what could be many sires, so if a later one matches your where you won't find it?

query = query.Where(x => 
    x.Lineages.FirstOrDefault(lineage => lineage.Sire.Contains(options.PedigreeContains))).Sire;

Upvotes: 0

John Saunders
John Saunders

Reputation: 161831

What if FirstOrDefault returns the "Default"? You'll get a NullReferenceException.

Upvotes: 1

Related Questions