Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.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查询巨大的CSV和Excel_C#_Sql_Excel_Linq_Csv - Fatal编程技术网

C# 使用LINQ查询巨大的CSV和Excel

C# 使用LINQ查询巨大的CSV和Excel,c#,sql,excel,linq,csv,C#,Sql,Excel,Linq,Csv,我试图找到方法来访问巨大的Excel或CSV文件,并执行聚合操作,如求和、计数和某些类似SQL的操作,如选择、分组等。 我知道LINQ可以帮我做到这一点。我更喜欢使用C。我的问题是: 1执行任何查询时,excel或CSV中的数据是否会加载到内存中?所有文件都在12GB左右。我问的原因是我不希望应用程序挂起 2我可以创建一个表单应用程序,其中我有一个文本区域,列出CSV/Excel的所有列。用户可以选择文本区域中的任何列。我计划使用SQL选项,如选择、分组、求和、平均值和许多其他选项。用户可以选择

我试图找到方法来访问巨大的Excel或CSV文件,并执行聚合操作,如求和、计数和某些类似SQL的操作,如选择、分组等。 我知道LINQ可以帮我做到这一点。我更喜欢使用C。我的问题是:

1执行任何查询时,excel或CSV中的数据是否会加载到内存中?所有文件都在12GB左右。我问的原因是我不希望应用程序挂起

2我可以创建一个表单应用程序,其中我有一个文本区域,列出CSV/Excel的所有列。用户可以选择文本区域中的任何列。我计划使用SQL选项,如选择、分组、求和、平均值和许多其他选项。用户可以选择其中的一个,然后在内部使用LINQ构建查询并获得结果。结果可以存储在文本文件中

我不确定这是否可行。请就此向我提出建议。我不熟悉使用LINQ。 如果无法通过LINQ实现这一点,请您建议其他有效的方法


提前感谢。

内存不是你的问题,性能是你的问题

我完全同意关于将其加载到适当的数据库中的意见,该数据库将索引行等,以使其更高效。尽管如此,如果直接读取CSV是非常不可取的,那么执行您描述的各种查询是可能的和直接的

我认为在这个任务中测试会很有趣

由于没有任何现成的大型csv文件,我只生成了一个具有以下标题的文件:

"row,Guid,Grouping1,Grouping2,Metric1,Metric2"
其中row是行号,Guid只是一个随机Guid Grouping1是一个介于0和49之间的随机整数,Grouping2是介于0和50000之间的随机整数,Metric1和Metric2分别是随机整数和双精度整数。基本上只是一些随机数据

然后我生成了一个包含9999999行的7Gb+文件…我的目标是100000000行,但在某个地方遇到了我的零索引盲点

好消息是LINQtoCSV将很高兴地解析这个坏小子,而不必将文件加载到内存中。只需在csv中创建一行表示的类:

    class Entry
    {
        [CsvColumn(FieldIndex = 1, Name="row")]
        public long Id { get; set; }

        [CsvColumn(FieldIndex = 2)]
        public string Guid { get; set; }

        [CsvColumn(FieldIndex = 3)]
        public int Grouping1 { get; set; }

        [CsvColumn(FieldIndex = 4)]
        public int Grouping2 { get; set; }

        [CsvColumn(FieldIndex = 5)]
        public int Metric1 { get; set; }

        [CsvColumn(FieldIndex = 6)]
        public double Metric2 { get; set; }
    }
然后将条目读入IEnumerable:


查询该文件大约需要25分钟。如果这不能使您将其放入一个正确索引的数据库中,那么什么都不会

您是否尝试过,但失败了?excel文件是真正的excel文件还是扩展名为.xls/.xlsx的text/csv文件?答案:1这取决于您将编写的查询。如果你擅长编程,你可以,否则你就不行。请认真阅读,以了解如何在堆栈溢出问题上提问。可能需要考虑将文件加载到DB中,因为它是为查询而设计的。
    IEnumerable<Entry> ReadEntries()
    {
        CsvFileDescription inputFileDescription = new CsvFileDescription
        {
            SeparatorChar = ',',
            FirstLineHasColumnNames = true
        };

        CsvContext ctx = new CsvContext();

        return ctx.Read<Entry>("test.csv", inputFileDescription);
    }
    static IEnumerable<Entry> entries;

    static void Main(string[] args)
    {
        entries = ReadEntries();

        var tasks = new List<Task> {timeEntryCount,timeEntryCountWhereG1_equals_1,timeMetric2SumWhereG2_equals_1};

        tasks.ForEach(t => t.Start());

        Task.WaitAll(tasks.ToArray());

        Console.WriteLine("Entry count took " + timeEntryCount.Result);
        Console.WriteLine("Entry count where G1==1 took " + timeEntryCountWhereG1_equals_1.Result);
        Console.WriteLine("Metric1 sum where G2==1 took " + timeMetric2SumWhereG2_equals_1.Result);
        Console.ReadLine();
    }

    static Task<TimeSpan> timeMetric2SumWhereG2_equals_1 = new Task<TimeSpan>(() =>
    {
        DateTime start = DateTime.Now;
        double sum = entries
            .Where(e => e.Grouping2 == 1)
            .Sum(e=>e.Metric2);
        Console.WriteLine("sum: " + sum);
        DateTime end = DateTime.Now;
        return end - start;
    },TaskCreationOptions.LongRunning);

    static Task<TimeSpan> timeEntryCountWhereG1_equals_1 = new Task<TimeSpan>(() =>
    {
        DateTime start = DateTime.Now;
        long count = entries
            .Where(e=>e.Grouping1==1)
            .Count();
        DateTime end = DateTime.Now;
        Console.WriteLine("countG1: " + count);
        return end - start;
    }, TaskCreationOptions.LongRunning);

    static Task<TimeSpan> timeEntryCount = new Task<TimeSpan>(() =>
    {
        DateTime start = DateTime.Now;
        long count = entries.Count();
        Console.WriteLine("CountAll: " + count);
        DateTime end = DateTime.Now;
        return end - start;
    }, TaskCreationOptions.LongRunning);
countG1: 2003023
CountAll: 99999999
sum: 1236810295.16543
Entry count took 00:25:26.3767852
Entry count where G1==1 took 00:24:41.9855814
Metric1 sum where G2==1 took 00:25:30.9080960