I have a simple SQL table which defines a set of hierarchical categories and sub-categories – note the ParentCategoryId can be null for ‘top-level’ categories…
CREATE TABLE [dbo].[Category](
[CategoryId] [uniqueidentifier] NOT NULL,
[ParentCategoryId] [uniqueidentifier] NULL,
[Name] [nvarchar](50) NOT NULL
)
If I then construct a Linq expression to find a particular category by Name and ParentCategoryId, I find that I cannot get the correct result if I set a Guid? variable to null:
Guid? parentCategoryId = null;
var category = dc.Categories
.Where(c => (
(c.Name == "Fred") &&
(c.ParentCategoryId == parentCategoryId)
));
This does not yield the same result as:
var category = dc.Categories
.Where(c => (
(c.Name == "Fred") &&
(c.ParentCategoryId == null)
));
From what I can find on the web, others have had this problem, but I haven’t been able to find a clean workaround to fix the problem.
Any ideas would be much appreciated. Thanks.
Additional Information
Here is the LINQ generated SQL statements for firstly a Guid? null parameter and then for a simple null parameter:
-- With Guid? null parameter : return an empty record set
DECLARE @p0 NVarChar(1000) SET @p0 = 'Fred'
DECLARE @p1 UniqueIdentifier SET @p1 = null
SELECT [t0].[CategoryId], [t0].[ParentCategoryId], [t0].[Name], [t0].[Timestamp]
FROM [dbo].[cad_ScoCategory] AS [t0]
WHERE ([t0].[Name] = @p0) AND ([t0].[ParentCategoryId] = @p1)
-- With null parameter - returns a single (correct) record
DECLARE @p0 NVarChar(1000) SET @p0 = 'Fred'
SELECT [t0].[CategoryId], [t0].[ParentCategoryId], [t0].[Name], [t0].[Timestamp]
FROM [dbo].[cad_ScoCategory] AS [t0]
WHERE ([t0].[Name] = @p0) AND ([t0].[ParentCategoryId] IS NULL)
As you can see, the first option compares the ParentCategoryId with a nulled paraemeter where as the second method checks ParentCategoryId IS NULL – which is correct
No, this is a reasonably common problem unfortunately. The workaround is to explicitly compare with null:
Alternatively, perform the check outside the query (to change which filter is used):