Search code examples
c#csvlinq

Only the first LINQ .Count() statement works


I've tried to get data from cvs file and everything went smoothly but I can't use LINQ on it,first statement always works but then the rest always returns 0

CVS header:car_make,car_model,car_model_year,car_vin

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>();
           
        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);
          
    }
}
namespace CSV_Deserialization
{
    public class Cars
    {
        [Name("car_make")]
        public string CarMake { get; set;}
        [Name("car_model")]
        public string CarModel { get; set; }
        [Name("car_model_year")]
        public int CarModelYear { get; set; }
        [Name("car_vin")]
        public string CarVin {  get; set; }

    }
}

namespace CSV_Deserialization
{
    public class MyCarMap :ClassMap<Cars>
    {
        public MyCarMap()
        {
            Map(m => m.CarMake).Name("car_make");
            Map(m => m.CarModel).Name("car_model");
            Map(m => m.CarModelYear).Name("car_model_year");
            Map(m => m.CarVin).Name("car_vin");
        }
       
    }
}

It doesn't work with Map or Indexes

I've tried changing csv,indexes and checked them


Solution

  • Just add .ToArray() or .ToList() after .GetRecords<Cars>():

    var records = csv.GetRecords<Cars>().ToArray();
    

    The GetRecords<T> method will return an IEnumerable<T>. It's reading the records until the end on the first Count() call and keeps pointing to the end on the second and third calls. That's why it returns the correct count only on the first.

    By calling ToArray or ToList, we are materializing the records.