Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在同一数据文件上运行多个LINQ查询_C#_Linq - Fatal编程技术网

C# 如何在同一数据文件上运行多个LINQ查询

C# 如何在同一数据文件上运行多个LINQ查询,c#,linq,C#,Linq,我不熟悉LINQ,目前正在使用它处理csv格式的大型数据集(50万条记录)。我正在使用StreamReader打开文件并实现IEnumerable接口以填充结果。下面您可以看到阅读代码的主要部分: IEnumerator<Person> IEnumerable<Person>.GetEnumerator() { using (StreamReader streamReader = new StreamReader(filename)){ strea

我不熟悉
LINQ
,目前正在使用它处理csv格式的大型数据集(50万条记录)。我正在使用
StreamReader
打开文件并实现
IEnumerable
接口以填充结果。下面您可以看到阅读代码的主要部分:

IEnumerator<Person> IEnumerable<Person>.GetEnumerator()
{
    using (StreamReader streamReader = new StreamReader(filename)){
        streamReader.ReadLine();
        while (!streamReader.EndOfStream){
            string[] values = streamReader.ReadLine().Split(new char[] { ',' });
            Person p = new Person();
            p.Name = values[0];
            p.Age = Convert.ToInt16(values[1]);
            p.Score = Convert.ToDouble(values[2]);
            p.PlotArea = Convert.ToInt16(values[3]);
            p.ForecastConsumption = Convert.ToDouble(values[4]);
            p.Postcode = values[5];
            p.PropertyType = values[6];
            p.Bedrooms = Convert.ToInt16(values[7]);
            p.Occupancy = Convert.ToInt16(values[8]);

            yield return p;
        }
    }
}
IEnumerator IEnumerable.GetEnumerator()
{
使用(StreamReader StreamReader=新StreamReader(文件名)){
streamReader.ReadLine();
而(!streamReader.EndOfStream){
string[]values=streamReader.ReadLine().Split(新字符[]{',});
人员p=新人员();
p、 名称=值[0];
p、 年龄=转换为16(值[1]);
p、 分数=Convert.ToDouble(值[2]);
p、 PlotArea=Convert.ToInt16(值[3]);
p、 ForecastConsumption=Convert.ToDouble(值[4]);
p、 邮政编码=数值[5];
p、 PropertyType=值[6];
p、 卧室=转换为16(值[7]);
p、 占用率=转换为16(值[8]);
收益率p;
}
}
}
下面是一个典型的查询:

var query = from person in reader
            where person.Score > 36.55 && person.Bedrooms < 3
            select person;
var query=来自读卡器中的人员
其中人员得分>36.55且人员卧室<3
选择人员;
我的问题是,每次我想运行一个查询,
StreamReader
都必须打开该文件。是否有任何方法可以一次打开文件并运行多个查询

仅供参考,我对LINQ印象深刻,运行上面的查询需要1.2秒。只是我会为数据集运行很多规则

我的问题是,每次我想运行查询时,StreamReader都必须打开文件。是否有任何方法可以一次打开文件并运行多个查询

最简单的方法是将整个文件加载到一个列表中,例如

var list = reader.ToList();

// Now run multiple queries over list
显然,这将占用大量内存,但这将是最简单的方法。如果要将多个查询连接在一起,则必须准确地确定要执行的操作—LINQ中的组合模型主要是将查询操作链接在一起,而不是从同一个源构建多个查询

否则,如果“一次查询多个”或“将整个文件加载到内存”的复杂性对您都不起作用,那么您很可能会被多次加载所困扰

中间的一个可能更高效的选项是将所有行读取到内存中(因此只执行一次磁盘活动),然后多次解析这些行。这将在IO方面更有效,但在CPU方面更糟糕

我的问题是,每次我想运行查询时,StreamReader都必须打开文件。是否有任何方法可以一次打开文件并运行多个查询

最简单的方法是将整个文件加载到一个列表中,例如

var list = reader.ToList();

// Now run multiple queries over list
显然,这将占用大量内存,但这将是最简单的方法。如果要将多个查询连接在一起,则必须准确地确定要执行的操作—LINQ中的组合模型主要是将查询操作链接在一起,而不是从同一个源构建多个查询

否则,如果“一次查询多个”或“将整个文件加载到内存”的复杂性对您都不起作用,那么您很可能会被多次加载所困扰


中间的一个可能更高效的选项是将所有行读取到内存中(因此只执行一次磁盘活动),然后多次解析这些行。这在IO方面效率更高,但在CPU方面更差。

您的情况将是在以下两个方面进行性能权衡:

  • 将整个文件读入内存,并运行所需的任何查询
  • 只需在文件上迭代多次
  • 如果是后者,请尝试使用
    File.ReadLines
    ,它在文件IO上提供了一个很好的IEnumerable接口:

    public Person ReadPerson(string[] personLine)
    {
        Person p = new Person();
        p.Name = personLine[0];
        p.Age = Convert.ToInt16(personLine[1]);
        p.Score = Convert.ToDouble(personLine[2]);
        p.PlotArea = Convert.ToInt16(personLine[3]);
        p.ForecastConsumption = Convert.ToDouble(personLine[4]);
        p.Postcode = personLine[5];
        p.PropertyType = personLine[6];
        p.Bedrooms = Convert.ToInt16(personLine[7]);
        p.Occupancy = Convert.ToInt16(personLine[8]);
    }
    
    使用方法:

    var file = File.ReadLines("/filepath/")
        .Select(line => ReadPerson(line.Split(',')));
    
    var query = from person in file
        where person.Score > 36.55 && person.Bedrooms < 3
        select person;
    
    var file=file.ReadLines(“/filepath/”)
    .Select(line=>ReadPerson(line.Split(','));
    var query=来自文件中的人员
    其中人员得分>36.55且人员卧室<3
    选择人员;
    
    您的情况将在以下两方面进行性能权衡:

  • 将整个文件读入内存,并运行所需的任何查询
  • 只需在文件上迭代多次
  • 如果是后者,请尝试使用
    File.ReadLines
    ,它在文件IO上提供了一个很好的IEnumerable接口:

    public Person ReadPerson(string[] personLine)
    {
        Person p = new Person();
        p.Name = personLine[0];
        p.Age = Convert.ToInt16(personLine[1]);
        p.Score = Convert.ToDouble(personLine[2]);
        p.PlotArea = Convert.ToInt16(personLine[3]);
        p.ForecastConsumption = Convert.ToDouble(personLine[4]);
        p.Postcode = personLine[5];
        p.PropertyType = personLine[6];
        p.Bedrooms = Convert.ToInt16(personLine[7]);
        p.Occupancy = Convert.ToInt16(personLine[8]);
    }
    
    使用方法:

    var file = File.ReadLines("/filepath/")
        .Select(line => ReadPerson(line.Split(',')));
    
    var query = from person in file
        where person.Score > 36.55 && person.Bedrooms < 3
        select person;
    
    var file=file.ReadLines(“/filepath/”)
    .Select(line=>ReadPerson(line.Split(','));
    var query=来自文件中的人员
    其中人员得分>36.55且人员卧室<3
    选择人员;
    
    这应该可以:

      return from line in File.ReadAllLines(filename)
                         let values = line.Split(new char[] { ',' })
                         select new Person{
                    Name = values[0];
                    Age = Convert.ToInt16(values[1]);
                    Score = Convert.ToDouble(values[2]);
                    PlotArea = Convert.ToInt16(values[3]);
                    ForecastConsumption = Convert.ToDouble(values[4]);
                    Postcode = values[5];
                    PropertyType = values[6];
                    Bedrooms = Convert.ToInt16(values[7]);
                    Occupancy = Convert.ToInt16(values[8]);
                };
    
    这应该起作用:

      return from line in File.ReadAllLines(filename)
                         let values = line.Split(new char[] { ',' })
                         select new Person{
                    Name = values[0];
                    Age = Convert.ToInt16(values[1]);
                    Score = Convert.ToDouble(values[2]);
                    PlotArea = Convert.ToInt16(values[3]);
                    ForecastConsumption = Convert.ToDouble(values[4]);
                    Postcode = values[5];
                    PropertyType = values[6];
                    Bedrooms = Convert.ToInt16(values[7]);
                    Occupancy = Convert.ToInt16(values[8]);
                };
    

    如果您是.net4+,您可以完全不用StreamReader,而是使用File.ReadLines。它做同样的事情(即允许您枚举文件而不将其全部加载到内存中)。
    reader
    是什么类型?如果你想在内存中完成所有工作,你也可以使用
    File.ReadAllLines
    看看这个,如果文件很大,你可以从它开始构建一个共享(多线程)缓存(只需记住每个线程库中的当前行/位置)我也喜欢LINQ,但是在没有LINQ的情况下重写该查询,只需要不到一秒钟的时间(如果你牺牲一点代码,我会说半秒)。如果你是.net4+,你可以完全不用StreamReader,而是使用File.ReadLines。它做同样的事情(即允许你枚举一个文件而不将其全部加载到内存中).
    reader
    是什么类型?如果您想在内存中完成所有操作,也可以使用
    文件。ReadAllLines
    看看这个,如果文件很大,您可以从它开始构建共享(多线程)cach