在代码中进行时 IEnumerable<> 变为 null

Syl*_* C. 0 c# .net-core

我使用 .Net Core 编写了一个非常简单的 Windows 应用程序,它生成一个包含 1000 条记录的 IEnumerable。在以下示例代码中,我的 IEnumerable 返回正确的记录,而第二行代码返回 null。

IEnumerable<test> myList = null; 
myList     = from item in myTable select ....();        
var result = myList.ToList();  //myList has 1000 records                  
int total  = myList.Count(); //myList is null
Run Code Online (Sandbox Code Playgroud)

我不明白为什么myList不持久化而改为null. 看起来好像用过一次就被冲掉了。


请看下面的真实代码:

using var dbContextTransation = _context.Database.BeginTransaction();
try
{
    IEnumerable<BuoyLocation> positionList = null; 
    var allPosition = csvReader.GetRecords<MyFormat>();
    
    positionList =
        from location in allPosition
        select new Location()
        {                                              
            LocationDateTime = location.Fecha.Add(new TimeSpan( Convert.ToInt32( location.Hora.Left(2) ), Convert.ToInt32( location.Hora.Right(2) ), 0 ) ),                                               
            Latitude         = location.Latitud,
            Longitude        = location.Longitud
        };  
    
    var result = positionList.ToList();//List has 1000 records 
    int total = positionList.Count(); //List is null
        
    ....
    dbContextTransation.Commit();
//  _context.Dispose();
    Console.WriteLine("Committed " + DateTime.Now);
    
}
catch (Exception ex)
{
    dbContextTransation.Rollback();
    LogService.LogWrite(textFile, "ERR:" + ex.Message + " ->" + ex.InnerException.Message);                        
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

谢谢

Jon*_*ter 5

您没有提到您正在使用 CsvHelper。

如此处所述: https://joshclose.github.io/CsvHelper/getting-started/

“GetRecords 方法将返回一个 IEnumerable,该 IEnumerable 将生成记录。这意味着当您迭代记录时,一次仅返回一条记录。这也意味着仅将文件的一小部分读入内存。不过要小心。如果您执行任何执行 LINQ 投影的操作,例如调用 .ToList(),整个文件将被读入内存。CsvReader 只向前,因此如果您想对数据运行任何 LINQ 查询,您'你必须将整个文件拉入内存。只要知道这就是你正在做的事情即可。”

CSVReader 使用 StreamReader,它不会在两次调用之间重置。由于您已经通过调用 ToList 将整个文件读取到列表中,因此只需使用结果变量即可执行您想要执行的操作。

如果您只想知道计数,而不对结果执行任何操作,那么在 myList 变量上调用 Count() 应该可以正常工作。

如果由于某种原因,您仍然想对初始变量进行计数,则应该重置流。CsvHelper的文档中也提到了这一点:

https://joshclose.github.io/CsvHelper/examples/preventions/streams/

例子:

using (var stream = new File.OpenRead("path\\to\\file"))
using (var reader = new StreamReader(stream))
{   
    // Read file content.
    var content = reader.ReadToEnd();

    // Go back to beginning of the stream.
    stream.Position = 0;

    // Read file content again.
    content = reader.ReadToEnd();
}
Run Code Online (Sandbox Code Playgroud)