3

I am a learner in C#. I want to read a particular value from the CSV file. I have learned the getting the csv file into a datatable through browsing. Please see the following code (Thanks to surendra jha) and my CSV file format. Say, I want to get what is the 'Volume' for 'ID' = 90.

CSV file

ID:Volume:Name
100:5600:A
95:5000:B
90:4500:C
85:4000:D

Code for getting all the values:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Data;              
namespace DVHConsolePrj
{
   class Program
     {
       static void Main(string[] args)
         {
             readCsvFileData();
          }
        static void readCsvFileData()
         {            
            string path = @"C:\IDVolumeName.txt";           
            StreamReader streamreader = new StreamReader(path);
            DataTable datatable = new DataTable();
            int rowcount = 0;
            string[] columnname = null;
            string[] streamdatavalue = null;
            while (!streamreader.EndOfStream)
            {
               string streamrowdata = streamreader.ReadLine().Trim();
                 if (streamrowdata.Length > 0) 
                    {
                       streamdatavalue = streamrowdata.Split(':'); 
                       if (rowcount == 0)
                       {
                          rowcount = 1;
                          columnname = streamdatavalue;
                          foreach (string csvheader in columnname)
                          {
                             DataColumn datacolumn = new DataColumn(csvheader.ToUpper(), typeof(string));
                             datacolumn.DefaultValue = string.Empty;
                             datatable.Columns.Add(datacolumn);
                           }
                        }
                        else
                        {
                          DataRow datarow = datatable.NewRow();
                          for (int i = 0; i < columnname.Length; i++)
                          {
                           datarow[columnname[i]] = streamdatavalue[i] == null ?             string.Empty : streamdatavalue[i].ToString();
                           }
                           datatable.Rows.Add(datarow);
                         }
                   }
          }
          streamreader.Close();
          streamreader.Dispose();                         
          foreach (DataRow dr in datatable.Rows)
          {
              string rowvalues = string.Empty;
              foreach (string csvcolumns in columnname)
              {
                  rowvalues += csvcolumns + "=" + dr[csvcolumns].ToString() + "    ";
               }
              Console.WriteLine(rowvalues);
            }
           Console.ReadLine();
           }              
        }
     }
4
  • Search in google how to read csv file with C#. Here an example ! stackoverflow.com/questions/5282999/…. Anyway I strongly advice you to use OleDbConnection ! Commented Dec 9, 2014 at 12:21
  • you can use DataTable.Select method for filtering Commented Dec 9, 2014 at 12:30
  • I have never seen a csv file with : for delimiters before. I thought CSV stands for comma separated values. Commented Dec 9, 2014 at 13:33
  • But, I have a small probs.... Using the following code, I can retrieve 95 to 85 but not 100? I am puzzled. Here is the code which replaces 'foreach (DataRow..' string myID; Console.Write("Enter ID:"); myID = Console.ReadLine(); var filtered = datatable.Select(String.Format("ID = {0}", myID)); if (filtered.Length > 0) { var Volume1 = filtered[0]["VOLUME"]; Console.WriteLine("Volume is :{0}",Volume1); } Console.ReadLine(); Commented Dec 9, 2014 at 15:06

3 Answers 3

2

Instead of parsing the file manually in a DataTable, then doing some Linq, use Linq directly on it, using this library.

It works pretty well and is very efficient with big files.

For instance.

1) Add nuget package in your project, and the following line to be able to use it:

using LINQtoCSV;

2) define the class that olds the data

public class IdVolumeNameRow
{
    [CsvColumn(FieldIndex = 1)]
    public string ID { get; set; }

    [CsvColumn(FieldIndex = 2)]
    public decimal Volume { get; set; }

    [CsvColumn(FieldIndex = 3)]
    public string Name{ get; set; }
}

3) and search for the value

    var csvAttributes = new CsvFileDescription
    {
        SeparatorChar = ':',
        FirstLineHasColumnNames = true
    };

    var cc = new CsvContext();

    var volume = cc.Read<IdVolumeNameRow>(@"C:\IDVolumeName.txt", csvAttributes)
            .Where(i => i.ID == "90")
            .Select(i => i.Volume)
            .FirstOrDefault();
Sign up to request clarification or add additional context in comments.

Comments

1
public DataTable CSVToDataTable(string filename, string separator)
{
    try
    {
        FileInfo file = new FileInfo(filename);

        OleDbConnection con = 
            new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"" +
            file.DirectoryName + "\";
            Extended Properties='text;HDR=Yes;FMT=Delimited(" + separator + ")';")

        OleDbCommand cmd = new OleDbCommand(string.Format
                                  ("SELECT * FROM [{0}]", file.Name), con);

        con.Open();

        DataTable tbl = new DataTable();

        using (OleDbDataAdapter adp = new OleDbDataAdapter(cmd))
        {
            tbl = new DataTable("MyTable");
            adp.Fill(tbl);        
        }

        return tbl;
     }
     catch(Exception ex)
     {
         throw ex;
     }
     finally()
     {
        con.Close();
     }  
} 

You can try this code, it is build on the fly, it is possible little errors to exist. Check OleDbConnection. When you return the DataTable you can search in the table using LINQ.

var results = from myRow in myDataTable.AsEnumerable()
where myRow.Field<int>("ID") == 90
select myRow;

Here you can take the row with ID=90 !

6 Comments

how does this answer his question?
Easy, I return the CSV file in the DataTable. After that I'm using LINQ to find the correct value.
His question is explicitly how to get the Volume for ID 90. Your answer does not cover it in the slightest.
@Serv now you can check it how. I wrote it explicit he can LINQ the dataTable for every value.
Now that's more like it.
|
0

For filtering DataTable you can use DataTable.Select method like this

var filtered = dataTable.Select("ID = '90'");

filtered above is array of datarow that suitable for the condition, so for get value from first filtered row you can use something like

if(filtered.Length>0){
    var Volume = filtered[0]["VOLUME"];
}

6 Comments

string myID; Console.Write("Enter ID:"); myID = Console.ReadLine(); var filtered = datatable.Select(String.Format("ID = {0}", myID)); if (filtered.Length > 0) { var Volume1 = filtered[0]["VOLUME"]; Console.WriteLine("Volume is :{0}",Volume1); } Console.ReadLine();
Thanks.. But, I have a small probs.... Using the following code, I can retrieve 95 to 85 but not 100? I am puzzled.
@kmothpur, try change string format to String.Format("ID = '{0}'", myID)
I did actually used that String.Format only. I have uploaded the code in the comment.....
@kmothpur in string.Format from your comment - used simple place holder: {0}, in my comment: '{0}', i mean quotes around placeholder
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.