Skip to content

How to use "IS NULL" with LINQ to SQL

Another “gotcha” using LINQ to SQL that I’ve found if you wish to test for “null” on a nullable column in SQL Server using the “IS NULL” clause. See below, this C# statement does not return the results you would expect (Assume “ReadMessageTypeFields()” simply returns an IQueryable result):

return messageTypeFieldRepository.ReadMessageTypeFields().Where(x => x.MessageTypeID == messageTypeID).ToList();

Results undesired SQL query result:

[sourcecode language='sql']
SELECT [t2].[ID], [t2].[MessageTypeID], [t2].[Name], [t2].[ID2] AS [Status], [t2].[UpdatedAt], [t2].[value] AS [CreatedAt]
FROM (
SELECT [t0].[ID], [t0].[MessageTypeID], [t0].[Name], [t1].[ID] AS [ID2], [t0].[UpdatedAt], [t0].[CreatedAt] AS [value]
FROM [dbo].[MessageTypeField] AS [t0]
INNER JOIN [dbo].[Status] AS [t1] ON [t1].[ID] = [t0].[StatusID]
) AS [t2] WHERE [t2].[MessageTypeID] = NULL

Notice the "= NULL" test. In SQL Server you cannot return NULL records by testing by "= NULL", this must be "IS NULL". Which is fair enough, I can deal with that; however I assumed that any null test in LINQ would be evaluated to the most obviously desired sql query result, but this is not the case. It seems that if you are testing in .NET on an object that has been "assigned" null, this could be a string, nullable int or anything, this will always output the result as "x = NULL" in a query, which is generally not what you want, as that will return 0 records, but if the expression in linq is tested explicitly FOR "null" this results in "IS NULL" in SQL correctly. See below:

return messageTypeFieldRepository.ReadMessageTypeFields().Where(x => ((!messageTypeID.HasValue && x.MessageTypeID == null) || (messageTypeID.HasValue && x.MessageTypeID == messageTypeID))).ToList();

Results in correct SQL query:

[sourcecode language='sql']
SELECT [t2].[ID], [t2].[MessageTypeID], [t2].[Name], [t2].[ID2] AS [Status], [t2].[UpdatedAt], [t2].[value] AS [CreatedAt]
FROM (
SELECT [t0].[ID], [t0].[MessageTypeID], [t0].[Name], [t1].[ID] AS [ID2], [t0].[UpdatedAt], [t0].[CreatedAt] AS [value]
FROM [dbo].[MessageTypeField] AS [t0]
INNER JOIN [dbo].[Status] AS [t1] ON [t1].[ID] = [t0].[StatusID]
) AS [t2]
WHERE [t2].[MessageTypeID] IS NULL

Notice I test if the ID is null first, if it is, actually test for null, if it is not, actually test for explicit ID. Adds a little convolution to the code and a bit annoying to always cater for second checking, but this is price you pay for LINQ goodness I guess.

VN:F [1.9.1_1087]
Rating: 4.0/5 (2 votes cast)
VN:F [1.9.1_1087]
Rating: 0 (from 0 votes)
How to use "IS NULL" with LINQ to SQL, 4.0 out of 5 based on 2 ratings
Bookmark and Share
kick it on DotNetKicks.com
Shout it

NOW, FOR A WORD FROM OUR SPONSORS

One Comment

  1. To deal with NULL comparisons, simply use object.Equals() comparison rather than ==
    e.g.

    from o in messageTypeFieldRepository.ReadMessageTypeField()
    .Where(x => nt32.Equals(x.messageTypeID, messageTypeID)

    Source:
    http://social.msdn.microsoft.com/Forums/en-US/linqtosql/thread/5d21e48c-b1cb-424d-b146-6c2f064df40d/

    VA:F [1.9.1_1087]
    Rating: 5.0/5 (1 vote cast)
    VA:F [1.9.1_1087]
    Rating: 0 (from 0 votes)
    Posted on 28-Feb-09 at 9:18 pm | Permalink

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*
My name is Graham O'Neale and I'm a software architect from Gold Coast, Australia. I am an overtime thinker, full time coder and awake part time in the real world. I have a keen interest in software development, particularly in the realm of programming (C#, ASP.NET, ASP.NET MVC, LINQ (2 SQL), Entity Framework, Silverlight, Blend, WCF, WPF) and a keen interest in the cutting edge and innovation. I have a new found love for design patterns, ALT.NET practices and well crafted software architecture. The purpose of this blog is to express any thoughts, findings, tips and gripes along my travels in the wonderful world of coding and technology...