设置从CSV

问题描述:

var csv = 
    from line in File.ReadAllLines("C:/file.csv") 
    let customerRecord = line.Split(',') 
    select new Customer() 
     { 
      contactID = customerRecord[0], 
      surveyDate = customerRecord[1], 
      project = customerRecord[2], 
      projectCode = customerRecord[3] 
     }; 

public class Customer 
    { 
     public string contactID { get; set; } 
     public string surveyDate { get; set; } 
     public string project { get; set; } 
     public string projectCode { get; set; } 
    } 

变量类型我希望能够读取surveyDateDateTime,以便将它与其他DateTime领域,我加入到csv文件进行比较。设置从CSV

我试过只是在类中设置surveyDate为Date.Time,我已经试过在select语句转换,但都失败,出现以下错误:

FormatException: The string was not recognized as a valid DateTime. There is an unknown word starting at index 0.

我必须使用csv文件,所以我不能将数据添加到sql server。

contactID,responseDate,project,projectID
1,6/4/2009,0-3 months,1
2,6/11/2009,0-3 months,1

+0

它是如何格式化? – Ryan

+3

-1 _“但都失败”_这是什么意思,代码在哪里? –

+0

** customerRecord [1] ** –

权...因为你永远无法知道什么输入将从CSV你不能总是尝试和隐含的字符串转换为DateTime因为你想要做的转换选择一个字符串的方式是做一个扩展方法。

public static class StringExtensions 
    { 
    public static DateTime TryParseDate(this string strToParse) 
    { 
     DateTime dt = new DateTime(); 
     DateTime.TryParse(strToParse, out dt); 
     return dt; 
    } 
    } 

然后,当你想在选择转换做这样的:

var csv = from line in File.ReadAllLines("C:/file.csv") 
      let customerRecord = line.Split(',') 
      select new Customer() 
       { 
        contactID = customerRecord[0], 
        surveyDate = customerRecord[1].TryParseDate(), 
        project = customerRecord[2], 
        projectCode = customerRecord[3] 
       }; 

你有你自己的方法。希望这有助于你,并为你工作。

你想解析的字符串将被传递给方法,然后你可以处理它并返回一个有效的日期时间,处理不正确的输入。

http://msdn.microsoft.com/en-us/library/bb383977.aspx

请参阅此链接的解释

+0

感谢您的出色演练。这工作,我明白为什么我需要指定如何处理日期。 – Jim

+0

为什么不接受哪些不适用于此? – LukeHennerley

+0

对不起卢克。用户错误,我的一部分。我在这里学习绳索。有用。 – Jim

您应该将customerRecord[1]字符串转换为DateTime

var csv = 
    from line in File.ReadAllLines("C:/file.csv") 
    let customerRecord = line.Split(',') 
    select new Customer() 
     { 
      contactID = customerRecord[0], 
      surveyDate = DateTime.Parse(customerRecord[1]), 
      project = customerRecord[2], 
      projectCode = customerRecord[3] 
     }; 

public class Customer 
    { 
     public string contactID { get; set; } 
     public DateTime surveyDate { get; set; } 
     public string project { get; set; } 
     public string projectCode { get; set; } 
    } 

I've tried just setting surveyDate as Date.Time in the class, and I've tried converting it in the select statement, but both fail.

那么你需要做两件事。您需要更改属性类型(理想情况下固定命名同时遵循约定)更改您设置它的位置,可能使用DateTime.ParseExact,指定格式和可能的不变文化。

(我假设你知道文件的日期的格式 - 我会强烈建议您使用DateTime.ParseExact,而不是仅仅让框架的尝试各种格式,直到它找到一个其中工程。)

编辑:现在,我们已经看到了文件,它看起来像你想要要么

DateTime.ParseExact(text, "d/M/yyyy", CultureInfo.InvariantCulture) 

或:

DateTime.ParseExact(text, "M/d/yyyy", CultureInfo.InvariantCulture) 

...但我们不能分辨出哪个,因为我们不知道“6/4/2009”是指4月6日还是6月4日。

+0

FormatException:该字符串未被识别为有效的DateTime。有一个未知的单词从索引0开始。 – Jim

+0

@JimMelichar:那是暗示你使用了错误的格式。因为你没有告诉我们这些值是什么样的,或者你尝试了什么,所以很难进一步帮助... –

+0

Jim,Jon在这里是正确的,那不是我所期望的错误。这个日期的格式是什么? (保证你我的答案也行不通,但知道这种格式会让我们中的任何一个人认出Jon)。 –

您需要在阅读时解析它以及更改类型。我不确定你是如何尝试它的。另外,如果您知道格式,请使用DateTime.ParseExact

var csv = 
    from line in File.ReadAllLines("C:/file.csv") 
    let customerRecord = line.Split(',') 
    select new Customer() 
     { 
      contactID = customerRecord[0], 
      surveyDate = DateTime.Parse(customerRecord[1]), 
      project = customerRecord[2], 
      projectCode = customerRecord[3] 
     }; 

public class Customer 
{ 
    public string contactID { get; set; } 
    public DateTime surveyDate { get; set; } 
    public string project { get; set; } 
    public string projectCode { get; set; } 
}

从刚刚发布的错误判断,我认为它可能是双引号。尝试微调引号:

DateTime.Parse(customerRecord[1].Trim('"')) 
+0

这正是我第一次尝试它。作为示例,在csv文件中,日期存储为6/4/2009。没有DateTime.Parse代码,我得到一个错误:不能执行文本选择:不能隐式地将类型'字符串'转换为'System.DateTime' – Jim

+0

@JimMelichar:然后使用DateTime.ParseExact,它会工作。 – Ryan

+0

什么时候是6/4/2009?是在四月还是六月? (从文本或Excel或Calc类似的东西看它呢) –

改变Customer后,使SurveyDate是一个DateTime则:

select new Customer() 
    { 
     contactID = customerRecord[0], 
     surveyDate = DateTime.Parse(customerRecord[1]), 
     project = customerRecord[2], 
     projectCode = customerRecord[3] 
    }; 

您可能需要使用的ParseParseExact这需要一个格式字符串形式,可以肯定的正确的结果。该格式字符串取决于文件中使用的格式。

或者,您可以创建客户一个Parse静态方法:

public class Customer 
{ 
    public string contactID { get; set; } 
    public DateTime surveyDate { get; set; } 
    public string project { get; set; } 
    public string projectCode { get; set; } 
    public static Customer Parse(string line) 
    { 
     var parts = line.Split(','); 
     return new Customer{ 
     contactID = parts[0], 
     surveyDate = DateTime.Parse(customerRecord[1]), 
     project = customerRecord[2], 
     projectCode = customerRecord[3] 
     }; 
}; 

然后:

var csv = 
    from line in File.ReadLines("C:/file.csv") 
    select Customer.Parse(line); 

这有一个优势,如果从这样一个格式化字符串获得Customer发生不止一次在多个你的代码。它不必要地填充Customer与cruft,如果这是你做它的唯一的地方。请注意,我喜欢ReadLines而不是ReadAllLines,以便一次获得产品线,而不是在开始生产客户之前先阅读所有内容。

顺便提一下,.NET约定有利于属性名称上的大写字母。 SurveyDate而不是surveyDate

+0

乔恩 - 我很欣赏关于正确约定名称的说明。了解你对客户的说明,我认为这可能是我唯一称之为的地方。感谢您的小费。我相信我会回来的。 – Jim