Home > OS >  How can I have a datatable detect multiple columns when iterating through rows in C# with conditiona
How can I have a datatable detect multiple columns when iterating through rows in C# with conditiona

Time:10-23

I am new to C# and I have to rebuild a JavaScript program into C#.

This program involves reading a CSV file and iterating through it to detect different values and to produce outputs.

Here is an example of my code:

foreach(DataRow row in results.Rows)
{
    if (row["Date"].ToString().Substring(row["Date"].ToString().Length - 16) == "2021 12:00:00 AM") //Checks if the year is 2021 or not in the "date" column
    {
        if (row["State"].ToString() == "CA") //Looks for CA state in the "state" column, however, it appears to not be finding it?
        { //DOES NEEDED CALCULATIONS

Basically, the code detects the "2021" date just fine in the data table, but it can't find the CA state at all when iterating through the rows, therefore, the required calculations are never done.

Here is what the data table looks like: DataTable

Help is greatly appreciated, I been stuck on this for a while due to my lack of knowledge with C#.

CodePudding user response:

Odds are that there is some extra whitespace in row["State"]

Try this:

foreach(DataRow row in results.Rows)
    {if (row["Date"].ToString().Substring(row["Date"].ToString().Length - 16) == "2021 12:00:00 AM") //Checks if the year is 2021 or not in the "date" column
        {
            if (row["State"].ToString().Contains("CA")) //Looks for CA state in the "state" column, however, it appears to not be finding it?
            { //DOES NEEDED CALCULATIONS

That being said, all the previous comments are really helpful for your needs. Don't do your own CSV parsing if you don't have to. Don't work on DateTime as string. Make your own DTOs to represent records, instead of using DataTable.

Example:

    record Invoice
    {
        public int InvoiceNumber { get; set; }
        public DateTime Date { get; set; }
        public double Amount { get; set; }
        public string State { get; set; }
    }

    public void DoStuff()
    {
        var invoices = ReadInvoiceFile("Your/Path/Here.csv");
        foreach (var invoice in invoices)
        {
            if(invoice.Date.Year != 2021) continue;
            if (invoice.State.Contains("CA"))
            {
                //do CA specific stuff here
            }
        }
    }

    private List<Invoice> ReadInvoiceFile(string path)
    {
        //realistically you would use a 3rd party library to do this
    }

I would also add that you shouldn't be using inline literals in your code (such as 2021 or "CA" in my example). And making your behavior depend on an if statement around a hardcoded state and year violates the Open-Closed principle, and a good candidate for refactoring into a factory method. But lets take one step at a time.

  • Related