使用LINQ将CSV读取到对象时出现字符串格式错误

时间:2019-01-23 10:08:37

标签: c# linq csv double

我正在从CVS文件读取数据到 C#列表对象。我只能读取字符串值。当我尝试读取数值(在这种情况下为双精度)时,我得到输入字符串的格式不正确。任何人都可以显示 我该如何克服? 这是代码:

class:

 public class Loan
    {
        string applicationDT;
        string employeeID;
        string employeeName;
        double amount;
        string lonType;

        public void printLoan()
        {
            Console.WriteLine($" employeeName {employeeName} employee Id {employeeID}" +
                $"applicationDate {applicationDT} \namount {amount} loanType {lonType}");
        }

        public static Loan fromCVS(string csvLine)
        {
            string []values = csvLine.Split(',');
            Loan loanRecord = new Loan();
            loanRecord.employeeName = (values[3]);
            loanRecord.employeeID = (values[4]);
            loanRecord.applicationDT = (values[5]);
            loanRecord.amount = Convert.ToDouble(values[6]);
            loanRecord.lonType = (values[7]);
            return loanRecord;
        }
    }

主要:

static void Main()
{
    List<Loan> loans = File.ReadAllLines(@"C:\Users\0300Test.csv")
                                   .Skip(1)
                                   .Select(v => Loan.fromCVS(v))
                                   .ToList();
    foreach(Loan aLoan in loans)
    {
        aLoan.printLoan();
    }
}

CSV文件:

"APPROVAL_OFFICER_NAME","APPROVAL_OFFICER_ID","RELATIONSHIP_MANAGER_NAME","EMPLOYEE_NAME","EMPLOYEE_ID","APPLICATION_DATE_TIME","AMOUNT","TYPE_OF_LOAN"
"SAMPLNAME","988803","SAMPLNAME","SAMPLNAME","776667","1/22/2019 11:05:43 AM","321146.00","Top Up With Settlement"
"SAMPLNAME","988803","SAMPLNAME","SAMPLNAME","776667","1/22/2019 9:34:13 AM","90230.00","Top Up With Settlement"
"SAMPLNAME","988803","SAMPLNAME","SAMPLNAME","776667","1/22/2019 12:00:22 AM","5230.00","Top Up without Settlement"

2 个答案:

答案 0 :(得分:2)

显然,您的问题是当您想为amount分配值时

string []values = csvLine.Split(',');
double amount = Convert.ToDouble(values[6]);

当然,您已调试了代码。您认为values[6]的价值是什么?

在您的csv行示例中,看起来像是:"\"90230.00\""

因此它是一个以字符串引号开头和结尾的字符串。无法将该值转换为双精度值。

解决方案很简单:删除该值开头和结尾的字符串引号。

  amount = Double.Parse(value[6].SubString(1, value[6].Length-2));

顺便说一句,您是否要employeeName(以及所有其他名称)作为字符串SAMPLENAME还是应该用引号将其括起来:“ SAMPLENAME”(因此内部是“ \” SAMPLENAME \“”)?

如果要从所有值中删除这些开始和结束的字符串引号,请考虑为字符串创建扩展函数。参见extension methods demystified

public static IEnumerable<string> SplitAndRemoveQuotes(this string string)
{
    // TODO: handle null string
    var splitValues = string.Split(',');
    foreach(string splitValue in splitValues)
    {
         // if you are certain every split value starts and ends with string quote
         // TODO: throw exception if not start/end with string quote?
         yield return splitValue.SubString(1, splitValue.Length-2);
    }
}

因此,如果您的字符串格式为“ \” \“ \”“(以可读格式:”“”),则返回值将是只有一个引号(“)的字符串

用法:

public static Loan fromCVS(string csvLine)
{
    // TODO: exception if csvLine null or empty

    var splitWithoutQuotes = csvLine.SplitAndRemoveQuotes()
        .Skip(2)        // we don't need the first two values
        .Take(5)        // we only need the next five values
        .ToList();
    // TODO: exception if result not 5 items

    return new Loan
    {
        employeNames = splitWithoutQuotes[0],
        ...
        amount = Double.Parse(values[4]);
        ...
    };
}

答案 1 :(得分:0)

如果您查看数据

  

“ SAMPLNAME”,“ 988803”,“ SAMPLNAME”,“ SAMPLNAME”,“ 776667”,“ 2019年2月2日上午11:05:43”,“ 321146.00”,“有结算的充值”

您的每个参数都用引号引起来。

values[6]的值实际上是"321146.00",其周围带有,因此无法转换。

 var x = values[6].Replace("\"", string.Empty);