ASP.NET Core中如何通过LINQ依次获取指定CategoryID对应的每个SerialNumber
解决逐个获取Category关联SerialNumber的问题
看起来你现在的核心问题是每次循环都重新去数据库查询第一个序列号,自然没法依次拿到后续的。我给你两种方案,分别对应不同场景,你可以按需选择:
最优方案:直接遍历序列号序列(强烈推荐)
你完全不需要先拿count再循环,直接把对应CategoryID的所有SerialNumber查询出来(用EF的话这是延迟执行的,不会一下子把所有数据加载到内存,除非主动调用ToList()),然后逐个遍历处理就行。代码改成这样:
// 获取当前CategoryID对应的所有SerialNumber的查询序列(延迟执行,EF会优化成一次数据库查询) var serialNumbers = _db.Category .Where(a => a.CategoryID == categoryID) .Select(a => a.SerialNumber); // 直接遍历每个序列号,逐个处理 foreach (var serialNumber in serialNumbers) { var getDifferentSerialNumberforEachLoop = serialNumber; // 执行你的后续操作 // ..... }
为什么这是最优选择?
- 代码更简洁,逻辑直接对应你“处理每个序列号”的需求;
- EF会把这个查询转换成一次SQL请求,获取所有对应的数据,相比你原来每次循环查一次数据库,性能提升非常多;
- 即使数据量较大,EF Core默认会流式处理数据,不会一次性把所有数据加载到内存,不用担心内存压力。
备选方案:每次从数据库获取单个序列号(仅适用于超大数据量)
如果你真的必须每次只从数据库拿一个序列号(比如数据量大到内存完全装不下),可以用分页查询的方式,每次跳过前面已经处理过的数量,取一个。但要注意,这种方式每次循环都会发起一次数据库请求,性能很差,不到万不得已不要用:
// 先拿到总数量 int totalCount = _db.Category.Count(a => a.CategoryID == categoryID); for (int i = 0; i < totalCount; i++) { var serialNumber = _db.Category .Where(a => a.CategoryID == categoryID) .OrderBy(a => a.SerialNumber) // 必须排序!否则数据库返回的顺序可能不稳定,导致重复或遗漏 .Skip(i) .Take(1) .FirstOrDefault(); if (serialNumber == null) break; // 防止循环过程中数据被删除,导致索引越界 var getDifferentSerialNumberforEachLoop = serialNumber; // 执行你的后续操作 // ..... }
注意事项:
- 必须加上
OrderBy,否则数据库没有排序的话,每次返回的结果顺序可能不一样,会出现重复获取或者漏掉某些序列号的情况; - 这种方式的数据库查询次数等于总数量,性能消耗很大,只有当数据量真的大到无法一次性处理时才考虑。
关于你提到的TakeWhile
TakeWhile是用来获取序列中满足条件的连续元素,直到遇到第一个不满足条件的元素就停止,并不适合你的场景——你需要的是所有对应CategoryID的序列号,不是满足某个条件的子集,所以这个方法帮不上忙。
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

