Linq很奇怪或者我很蠢?

时间:2009-01-28 09:57:54

标签: c# linq-to-sql

为什么这样做:

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

但不是(结果为空):

String code = "";
String domain = null;

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

...

4 个答案:

答案 0 :(得分:6)

扩展Iain的答案:

根据e.Domain.Equals()的重载次数,传递空字符串变量可能会遇到与传递null不同的变量吗?我不确定这里的规则是什么,但我怀疑编译器在明确给出“just”null时,可能更喜欢e.Domain.Equals(对象变量)到e.Domain.Equals(字符串变量),而不是已设置为null的字符串变量?

答案 1 :(得分:4)

空字符串 - 域 - 与传递null不同?

答案 2 :(得分:4)

这确实听起来很奇怪。 LINQ to SQL可能会注意到从变量中获取值和从常量中获取值之间的区别,但我不希望它有任何区别。

我强烈建议,只要LINQ to SQL看起来行为奇怪,就可以打开上下文并查看它在每种情况下实际执行的查询。

编辑:围绕重载方面的其他答案非常有趣。如果您在第二个查询中将domain变量声明为object而不是string,或在第一个查询中将null强制转换为string,会发生什么?

答案 3 :(得分:1)

通过记录来计算出来,这些是我的结果:

我得到以下结果:

使用:

(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

不起作用:

(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

所以

将我的linq2sql重写为:

(from e in CampaignCodes where e.Code.Equals(code) && ((domain==null && e.Domain.Equals(null))||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 = 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

当域不为空时:

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

什么时候。

但是我希望有这样的方法......