仅首个LINQ .Count()语句生效,后续调用返回0的技术问题
解决CsvHelper多次调用Count()仅首次有效后续返回0的问题
问题核心在于csv.GetRecords<Cars>()返回的是延迟执行的IEnumerableCount())时,才从StreamReader逐行读取解析。
第一次调用Count()时,StreamReader已经读取到了文件末尾,指针停在最后位置。后续再调用Count()时,StreamReader没有剩余数据可以读取,自然返回0。
两种可行解决方案:
方案1:提前将数据加载到内存集合
把GetRecords()的结果转换成List<Cars>,这样所有数据都会被一次性加载到内存,后续多次枚举操作都是基于内存中的数据,不会再依赖StreamReader:
public static void Main(string[] args) { using (var reader = new StreamReader("D:\\C#\\CSV_Deserialization\\obj\\Debug\\net7.0\\Cars1.csv")) using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture)) { //csv.Context.RegisterClassMap<MyCarMap>(); var records = csv.GetRecords<Cars>().ToList(); // 关键:转成List加载到内存 int HondaCounter = records.Count(car => car.CarMake == "Honda"); int ChevroletCounter = records.Count(car => car.CarMake == "Chevrolet"); int PontiacCounter = records.Count(car => car.CarMake == "Pontiac"); Console.WriteLine(HondaCounter); Console.WriteLine(ChevroletCounter); Console.WriteLine(PontiacCounter); } }
方案2:一次性统计所有需要的计数
通过GroupBy一次性完成分组统计,避免多次枚举数据源,效率更高:
public static void Main(string[] args) { using (var reader = new StreamReader("D:\\C#\\CSV_Deserialization\\obj\\Debug\\net7.0\\Cars1.csv")) using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture)) { //csv.Context.RegisterClassMap<MyCarMap>(); var makeCounts = csv.GetRecords<Cars>() .GroupBy(car => car.CarMake) .ToDictionary(group => group.Key, group => group.Count()); int HondaCounter = makeCounts.TryGetValue("Honda", out var hCount) ? hCount : 0; int ChevroletCounter = makeCounts.TryGetValue("Chevrolet", out var cCount) ? cCount : 0; int PontiacCounter = makeCounts.TryGetValue("Pontiac", out var pCount) ? pCount : 0; Console.WriteLine(HondaCounter); Console.WriteLine(ChevroletCounter); Console.WriteLine(PontiacCounter); } }
不管你用属性[Name]标记还是ClassMap映射字段,只要解决了多次枚举延迟执行的IEnumerable问题,就能正常得到所有计数结果。
内容的提问来源于stack exchange,提问作者user23511784
相关产品推荐
相关产品推荐

