C#使用SQL条件读取CSV文件

时间:2017-02-12 21:30:01

标签: c# sql csv

我正在使用CsvHelper lib来读取CSV文件,我可以使用lib成功读取该文件。但是我不能使用SQL条件来过滤值。如何在不使用SQL Server的情况下执行此操作。我真的被困在了它上面。

使用Python中的Pandas和Pandasql库非常容易,但在C#中它太难了。

  

我的代码:

public static void Main(string[] args)
        {
            var fileInfo = new FileInfo(@"filePath");

            using (TextReader reader = fileInfo.OpenText())
            using (var csvReader = new CsvReader(reader))
            {
                csvReader.Configuration.Delimiter = ",";
                csvReader.Configuration.HasHeaderRecord = false;
                csvReader.Configuration.IgnoreQuotes = true;
                csvReader.Configuration.TrimFields = true;
                csvReader.Configuration.WillThrowOnMissingField = false;


                while (csvReader.Read())
                {
                    var myStrinVar = csvReader.GetField<string>(0);

                    Console.Write(myStrinVar); //SELECT * FROM table...
                }
            }
        }

2 个答案:

答案 0 :(得分:4)

我建议使用LINQ来过滤结果。

https://msdn.microsoft.com/en-us/library/bb397906.aspx

假设您有一些课程MyClass,您可以将文件中的行序列化。 例如:

public class MyClass
{
    public int ID { get; set; }
}

var records = csv.GetRecords<MyClass>().ToList();
var filtered = records.Where(r => r.ID >= 10);

这个例子有点做作,但你可以在where子句中使用你喜欢的任何布尔表达式。

答案 1 :(得分:0)

我知道这对于OP来说为时已晚,但是接受的答案的问题是您必须将整个结果集读入内存,这对于大型文件而言可能是站不住脚的。此外,如果您可以在下面扩展此代码以获取前N行,而不必在文件中的早期找到匹配项,则无需阅读整个CSV。

public static void Main(string[] args)
{
    var fileInfo = new FileInfo(@"filePath");
    var where = ""; //Code to set up where clause part of query goes here

    using (TextReader reader = fileInfo.OpenText())
        using (var csvReader = new CsvReader(reader))
        {
            csvReader.Configuration.Delimiter = ",";
            csvReader.Configuration.HasHeaderRecord = false;
            csvReader.Configuration.IgnoreQuotes = true;
            csvReader.Configuration.TrimFields = true;
            csvReader.Configuration.WillThrowOnMissingField = false;

            DataTable dt = null;
            while (csvReader.Read())
            {
                //Use the first row to initialize the columns.
                if (dt == null)
                {
                    dt = new DataTable();
                    for (var i = 0; i < csvReader.FieldCount; i++)
                    {
                        var fieldType = csvReader.GetFieldType(i);
                        DataColumn dc;
                        if (fieldType.IsNullableType())
                        {
                            dc = new DataColumn(csvReader.GetName(i), Nullable.GetUnderlyingType(fieldType));
                            dc.AllowDBNull = true;
                        }
                        else
                            dc = new DataColumn(csvReader.GetName(i), data.GetFieldType(i));
                        dt.Columns.Add(dc);
                    }
                }
               //Map DataReader to DataRow
               var newRow = dt.Rows.Add();
               foreach(DataColumn col in dt.Columns)
               {
                    newRow[col.ColumnName] = csvReader[col.ColumnName];
               }
            //Create a temporary DataView and filter it with the where clause.
            DataView dv = new DataView(dt);
            dv.RowFilter = where;
            var data = dv.Count > 0 ? dv[0] : null;
            if(data != null)
            {
                //Row in here matches your where clause.
                //Code to read this row or do something with it.
            }
            //Empty the temporary data table.
            dt.Rows.Clear();
        }
    }
}