2

Why does this work:

result = (from e in db.CampaignCodes where e.Code.Equals("") && 
e.Domain.Equals(null) select e).FirstOrDefault();

But not (result is null):

String code = "";
String domain = null;

result = (from e in db.CampaignCodes where e.Code.Equals(code) &&
 e.Domain.Equals(domain) select e).FirstOrDefault();

??

edosoft
  • 17,121
  • 25
  • 77
  • 111
Niels Bosma
  • 11,758
  • 29
  • 89
  • 148

4 Answers4

6

To expand on Iain's answer:

Depending on what overloads of e.Domain.Equals() there are, passing a null string variable may hit a different one than passing null? I'm not sure what the rules would be here, but I suspect the compiler might prefer an e.Domain.Equals(object variable) to e.Domain.Equals(string variable) when explicitly given "just" null, rather than a string variable that has been set as null?

Rob
  • 45,296
  • 24
  • 122
  • 150
4

a null string - domain - isn't the same as just passing null?

Iain
  • 9,432
  • 11
  • 47
  • 64
4

That does indeed sound quite odd. LINQ to SQL may well notice the difference between getting the value from a variable and getting it from a constant, but I wouldn't have expected it to make any difference.

I strongly recommend that whenever LINQ to SQL appears to be behaving oddly, you turn the context logging on and see what query it's actually executing in each case.

EDIT: The other answers around the overloading aspect are really interesting. What happens if you declare the domain variable as type object instead of string in the second query, or cast the null to string in the first query?

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    Not having gotten around to using LinqToSql yet, my answer is supposition - which probably means I'm overly complicating things! Yours is definitely the more "practically useful" answer =) – Rob Jan 28 '09 at 10:11
  • Certainly turning the log on should take at least *some* of the mystery away :) – Jon Skeet Jan 28 '09 at 10:20
  • I don't remember exactly what was the problem, but we did have some issues with comparing for null values. SQL compared things that were null a bit differently than is done in C#. – Svish Feb 20 '09 at 11:27
  • Yes, SQL null values aren't equal to anything else. – Jon Skeet Feb 20 '09 at 11:32
  • @Svish @Rob @Niels @Jon: See http://stackoverflow.com/questions/682429/how-can-i-query-for-null-values-in-entity-framework – BlueRaja - Danny Pflughoeft Sep 30 '10 at 18:32
1

Figuread it out through logging, these are my results:

I get the following results:

Works:

(from e in CampaignCodes where e.Code.Equals(code) && e.Domain.Equals(null) select e).FirstOrDefault().Dump();

SELECT TOP (1) [t0].[Id], [t0].[Code], [t0].[Domain], [t0].[ClientId], [t0].[CampaignId], [t0].[PathId], [t0].[DescriptionText], [t0].[DeleteFlag], [t0].[Created]
FROM [CampaignCodes] AS [t0]
WHERE ([t0].[Code] = @p0) AND ([t0].[Domain] IS NULL)
-- @p0: Input NVarChar (Size = 0; Prec = 0; Scale = 0) []
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.21022.8

Doesn't Work:

(from e in CampaignCodes where e.Code.Equals(code) && e.Domain.Equals(domain) select e).FirstOrDefault().Dump();

SELECT TOP (1) [t0].[Id], [t0].[Code], [t0].[Domain], [t0].[ClientId], [t0].[CampaignId], [t0].[PathId], [t0].[DescriptionText], [t0].[DeleteFlag], [t0].[Created]
FROM [CampaignCodes] AS [t0]
WHERE ([t0].[Code] = @p0) AND ([t0].[Domain] = @p1)
-- @p0: Input NVarChar (Size = 0; Prec = 0; Scale = 0) []
-- @p1: Input NVarChar (Size = 0; Prec = 0; Scale = 0) [Null]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.21022.

8

so

By rewriting my linq2sql to:

(from e in CampaignCodes where e.Code.Equals(code) && ((domain==null && e.Domain.Equals(null))||e.Domain.Equals(domain)) select e).FirstOrDefault().Dump();

I get:

SELECT TOP (1) [t0].[Id], [t0].[Code], [t0].[Domain], [t0].[ClientId], [t0].[CampaignId], [t0].[PathId], [t0].[DescriptionText], [t0].[DeleteFlag], [t0].[Created]
FROM [CampaignCodes] AS [t0]
WHERE ([t0].[Code] = @p0) AND ([t0].[Domain] = @p1)
-- @p0: Input NVarChar (Size = 4; Prec = 0; Scale = 0) [test]
-- @p1: Input NVarChar (Size = 14; Prec = 0; Scale = 0) [mydomain.se]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.21022.8

When domain isn't null and:

SELECT TOP (1) [t0].[Id], [t0].[Code], [t0].[Domain], [t0].[ClientId], [t0].[CampaignId], [t0].[PathId], [t0].[DescriptionText], [t0].[DeleteFlag], [t0].[Created]
FROM [CampaignCodes] AS [t0]
WHERE ([t0].[Code] = @p0) AND (([t0].[Domain] IS NULL) OR ([t0].[Domain] = @p1))
-- @p0: Input NVarChar (Size = 4; Prec = 0; Scale = 0) [test]
-- @p1: Input NVarChar (Size = 0; Prec = 0; Scale = 0) [Null]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.21022.8

When it is.

But I'd hoped that there would be a nices methods for this...

Niels Bosma
  • 11,758
  • 29
  • 89
  • 148