gpt4 book ai didi

c# - 当我将代码从 IEnumerable 更改为 List 时,为什么我的代码可以正常工作?

转载 作者:行者123 更新时间:2023-11-30 22:13:00 25 4
gpt4 key购买 nike

我正在努力解决这个问题,而不是仅仅将其归结为一般的巫术。

我执行 EF 查询并取回一些数据,然后我 .ToList()它,像这样:

IEnumerable<DatabaseMatch<CatName>> nameMatches = nameLogicMatcher.Match(myIQueryableOfCats).ToList();

有些猫在数据库中出现了两次,因为它们有多个名字,但每只猫都有一个主要名字。因此,为了对此进行过滤,我在列表中获取了所有猫的 ID:

List<int> catIds = nameMatches.Select(c => c.Match.CatId).ToList();

然后我遍历所有不同的 id,获取所有匹配的猫名称,并从列表中删除任何不是主要名称的内容,如下所示:

foreach (int catId in catIds.Distinct())
{
var allCatNameMatches = nameMatches.Where(c => c.Match.CatId == catId);

var primaryMatch = allCatNameMatches.FirstOrDefault(c => c.Match.NameType == "Primary Name");

nameMatches = nameMatches.Except(allCatNameMatches.Where(c => c != primaryMatch));
}

现在这段代码,当我第一次运行它时,只是挂起。我觉得这很奇怪。我逐步解决了它,它似乎可以工作,但在 10 次迭代后(它的上限为总共 100 只猫)它开始变慢,然后最终变得冰冷,然后完全挂起。

我认为它可能错误地执行了一些密集的数据库工作,但探查器显示除了检索猫名称的初始列表之外没有执行任何 SQL。

我决定将其从 IEnumerable 更改为名称匹配 List , 并放置适当的 .ToList()在最后一行。在我这样做之后,它立即完美运行。

我想问的问题是,为什么?

最佳答案

如果没有 ToList(),您将在 nameMatches 中构建一个等待延迟执行的嵌套 IEnumerable 链。这可能还不错,除非您还在每次执行链的迭代中调用 FirstOrDefault。因此,在 n 次迭代中,您将执行循环中包含的过滤操作 n-1 次。如果您有 1000 只不同的猫,Linq 链将执行 1000 + 99 + ... + 1 次。 (我认为你有一些O(n³)!)

道德是,如果你想使用延迟执行,请非常确保你只执行你的链一次。

关于c# - 当我将代码从 IEnumerable 更改为 List 时,为什么我的代码可以正常工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19400499/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com