0

我们有以下两个非常棒的查询。它们在各方面都是相同的,但有一个:其中一个指向代表 Entity Framework 到我的本地 SQL 服务器的连接的 IQueryable,另一个代表一个 List,理论上它包含完全相同的数据。

var databaseQuery = db.Table.First(Test);
var listQuery = list.First(Test);

在这种情况下,我以以下方式创建列表:

var list = db.Table.ToList();

没有什么花哨。我只想通过用几百兆内存换取我一生中半个小时的时间来改善我的开发机器上查询的糟糕性能。只有一个小问题:

var listQuery = list.First(Test);

我总是,总是,总是在那条线上得到一个例外,就在那里,说序列不包含匹配的元素。

到底是怎么回事?

编辑:既然你问得很好,本例中的测试比较了两个 long 的值。

进一步编辑:这是直接从 IDE 截取的实际代码。这个 .First() 被添加到 IQueryable 或 IEnumerable 的末尾——内存中的实体堆或到数据库的链接。

.First(v =>
    v.UserID == mm.SystemUserId
    && validMerchants.Contains(v.ActualMerchantId.Value));

Slauma:我没有说它永远不会为空。我只是说它为 null 会引发不同的异常。(你知道,这是有道理的。)

看来我得想办法加快速度了。

4

1 回答 1

0

我想不出任何应该触发这个的东西,除了如建议的那样,两种情况下 null 的不同行为但是我可以建议一种非常简单的方法来调试它

您说数据库版本返回结果但内存不返回结果,反过来会更难调试,但这很容易,从数据库版本结果集中,执行 .First() 并记下 ID

在 .First() 之前将内存中的一个更改为 .Where(检查您知道应该从数据库集中匹配的特定 ID)

在第一个 lambda 内放置一个断点(不是在 .First() 行,而是在 v=> 行),它应该只命中匹配的内容(因为您已经从 where 过滤了其他所有内容)。然后在该断点上,将 lambda 的内容复制/粘贴到即时窗口以查看它返回 false 的原因,测试这些内容,直到找到返回 false 的内容&然后应该很明显出了什么问题,如果它没有在此处发布结果&我们可以更深入地挖掘这个。

第一次测试:v.UserID == mm.SystemUserId && validMerchants.Contains(v.ActualMerchantId.Value) 第二次测试:v.UserID == mm.SystemUserId 第三次测试:validMerchants.Contains(v.ActualMerchantId.Value)

如果其中任何一个返回 false,那么您就知道它不匹配,是时候检查该数据并查看原因。如果一切都很好地返回真,首先应该返回那个元素并且你没有错误,所以我很确定“某事”会返回假。如果其中之一返回 false(v.UserId、mm.SystemUserId 和 v.ActualMerchantId.Value 的值),还请确保发布所有内容的结果

于 2013-10-15T05:50:48.710 回答