2

我正在使用 SqlMetal (linq to sql) 从数据库中检索内容。但是,我使用以下代码得到不同的结果:

var record1 = Enumerable.FirstOrDefault(_dataContext.StaticPageLangs, 
              r => r.selected_partial_url_id == partialUrlid 
                && r.selected_last_part_url_id == lastPartUrlId 
                && r.language_id == languageId);

var record2 = _dataContext.StaticPageLangs.FirstOrDefault(
              r => r.selected_partial_url_id == partialUrlid
                && r.selected_last_part_url_id == lastPartUrlId
                && r.language_id == languageId);

填充此记录 1 后,但记录 2 为 NULL,我希望它们相同。

谁能解释其中的区别?

编辑:

在旁注中:

r.selected_pa​​rtial_url_id 是可为空的 int,被比较的属性也是如此 r.selected_last_part_url_id 是 int 类型,被比较的属性也是如此 r.language_id 是 int 类型,被比较的属性也是

4

2 回答 2

5

第一个查询是在内存中完成的,因为您使用的是 Enumerable.FirstOrDefault(...)。第二个查询由数据上下文转换为 SQL,并由数据库执行。

您必须检查 sql 探查器以查看执行的实际查询是什么,以了解差异是什么。您的数据库中是否有任何可以为空的列可能是问题所在?

更新

如果您在一个被转换为 SQL 语句的表达式中比较可为空的属性,请注意,如果比较的两个值都为空,这可能会出错。例子:

_dataContext.StaticPageLangs
    .FirstOrDefault(r => r.selected_partial_url_id == partialUrlid)

如果 partialUrlid == NULL 并且存在 selected_pa​​rtial_url_id == NULL 的记录,则不会产生任何记录。原因:翻译后的 sql 包含 'selected_pa​​rtial_url_id == NULL' 而不是 'selected_pa​​rtial_url_id IS NULL'。

于 2012-07-25T12:31:08.827 回答
1

注意:以下答案适用于record1存在nullrecord2不存在null,这与问题相反,但可能对其他有类似情况的读者有用

如果我不得不猜测,其中至少有一个==在 a 上string,这是一个区分大小写的问题。

record1来自 LINQ-to-Objects,因此它从服务器中提取所有行,并在本地测试它们。这些==是区分大小写的(C# / .NET ==onstring始终区分大小写)。

record2看起来它正在通过IQueryable<>. 这意味着它正在被翻译成 TSQL。SQL-Server 数据库可以区分大小写或不区分大小写。我猜你把它设置为不区分大小写。

现在想象一下,那languageId"en-us"在 C# 和'EN-US'数据库中。

这可能导致record1成为null,但record2被填充。

于 2012-07-25T12:32:11.193 回答