有没有办法使用LinqToCSV并只选择特定的列?
例如,我需要每天摄取一个CSV文件,一个月可能有14列,也可能在一个月后有15列。目前我已将其配置为映射所有14列,但这确实不理想,因为我真正关心的只有10个。
因此,当抛出额外的列时,我会抛出一个TooManyDataFieldsException,LinqToCSV将不会读取CSV文件的任何行。
答案 0 :(得分:1)
见这里:http://www.codeproject.com/Articles/25133/LINQ-to-CSV-library#EnforceCsvColumnAttribute
如果为true,则只读将数据字段读入公共字段和 具有[CsvColumn]属性的属性,忽略所有其他字段 和属性。而且,Write只写入公共字段的内容 和[CsvColumn]属性的属性。
答案 1 :(得分:1)
似乎IgnoreUnknownColumns属性完成了这项工作,
这里是我使用的代码:
/// <summary>
/// The input file without header.
/// </summary>
private readonly CsvFileDescription inputFileWithoutHeader = new CsvFileDescription
{
SeparatorChar = ',',
FirstLineHasColumnNames = false,
EnforceCsvColumnAttribute = true,
IgnoreUnknownColumns = true
};
/// <summary>
/// The input file with headers.
/// </summary>
private readonly CsvFileDescription inputFileWithHeaders = new CsvFileDescription
{
SeparatorChar = ',',
FirstLineHasColumnNames = true,
EnforceCsvColumnAttribute = false,
IgnoreUnknownColumns = true
};
/// <summary>
/// The list items.
/// </summary>
/// <returns>
/// The <see>
/// <cref>IEnumerable</cref>
/// </see>
/// .
/// </returns>
public IEnumerable<ListItem> ListItems()
{
return
Directory.EnumerateFileSystemEntries(this.path, "ListItem*.csv")
.SelectMany(chkLstFile => this.csvContext.Read<ListItem>(chkLstFile, this.inputFileWithoutHeader)).Distinct();
}
然后我从我的存储库中检索我的数据:
var myItems = myClassInstance.ListItems().CatchExceptions(ex => Debug.WriteLine(ex.Message));
为了获得更多控制,我有一个扩展方法来处理来自以下方面的错误: Wrap an IEnumerable and catch exceptions
public static IEnumerable<T> CatchExceptions<T>(this IEnumerable<T> src, Action<Exception> action = null)
{
using (var enumerator = src.GetEnumerator())
{
var next = true;
while (next)
{
try
{
next = enumerator.MoveNext();
}
catch (AggregatedException ex)
{
lock (ex)
{
foreach (var e in ex.m_InnerExceptionsList)
{
if (action != null)
{
action(e);
}
File.AppendAllText(LogFilePath, string.Format("{0}: {1}\r\n", DateTime.Now.ToShortTimeString(), e.Message)); //todo ILogger
}
}
File.AppendAllText(LogFilePath, "-\r\n");
continue;
}
catch (Exception ex)
{
if (action != null)
{
action(ex);
}
lock (ex)
{
File.AppendAllText(LogFilePath, string.Format("{0}: {1}\r\n", DateTime.Now.ToShortTimeString(), ex.Message)); //todo ILogger
}
continue;
}
if (next)
{
yield return enumerator.Current;
}
}
}
}
答案 2 :(得分:0)
尝试实施IDataRow界面 - 请参阅"Reading Raw Data Rows"
答案 3 :(得分:0)
您需要IgnoreUnknownColumns http://www.codeproject.com/Articles/25133/LINQ-to-CSV-library#IgnoreUnknownColumns