tabs ↹ over ␣ ␣ ␣ spaces

by Jiří {x2} Činčura

Compare NULLs in database as in C# in Entity Framework

23 Apr 2012 2 mins C#, Databases in general, Entity Framework, Entity SQL, LINQ

Roughly two years ago I blogged about differences in NULLs handling in databases and in (some) programming languages (C# in particular). But Entity Framework 5 (in .NET 4.5) (lost?) comes with handy switch. It’s UseCSharpNullComparisonBehavior. What this basically does is ensure when you compare nullable fields to be handled like in C#, aka null == null and not like in SQL where NULL compared to anything is NULL or false when boolean value is needed.

Let’s have a look at the diffences. Simple code:

int? i = default(int);
using (testEntities c = new testEntities())
{
	c.ContextOptions.UseCSharpNullComparisonBehavior = true;
	Console.WriteLine((c.Details.Where(x => x.MasterID != i) as ObjectQuery).ToTraceString());
}
using (testovaciEntities c = new testovaciEntities())
{
	c.ContextOptions.UseCSharpNullComparisonBehavior = false;
	Console.WriteLine((c.Details.Where(x => x.MasterID != i) as ObjectQuery).ToTraceString());
}

The first query creates “magic” SQL:

SELECT
[Extent1].[ID] AS [ID],
[Extent1].[ID_MASTER] AS [ID_MASTER],
[Extent1].[BAR] AS [BAR]
FROM [dbo].[DETAIL] AS [Extent1]
WHERE  NOT ((([Extent1].[ID_MASTER] = @p__linq__0) AND ( NOT ([Extent1].[ID_MASTER] IS NULL OR @p__linq__0 IS NULL))) OR (([Extent1].[ID_MASTER] IS NULL) AND (@p__linq__0 IS NULL)))

While the other expected one:

SELECT
[Extent1].[ID] AS [ID],
[Extent1].[ID_MASTER] AS [ID_MASTER],
[Extent1].[BAR] AS [BAR]
FROM [dbo].[DETAIL] AS [Extent1]
WHERE [Extent1].[ID_MASTER] <> @p__linq__0

What the first one is doing is handling the case where C# null (in parameter) can be compared to database NULL to fix-up the logic.

If you’re not familiar with NULLs in database this can be tricky to handle correctly, especially if you have negations, Alls and Anys nested inside query. Hence setting this property to true can save you hours of debugging and wondering what’s going on.

Profile Picture Jiří Činčura is .NET, C# and Firebird expert. He focuses on data and business layers, language constructs, parallelism, databases and performance. For almost two decades he contributes to open-source, i.e. FirebirdClient. He works as a senior software engineer for Microsoft. Frequent speaker and blogger at www.tabsoverspaces.com.