4

有什么方法可以使用 LinqToCSV 并只选择特定的列?

例如,我需要每天摄取一个 CSV 文件,其中一个月可能有 14 列,下个月可能有 15 列。目前我已经将它配置为映射所有 14 列,但这确实不理想,因为我真正关心的只有 10 个。

因此,当我抛出一个额外的列时,我会抛出一个 TooManyDataFieldsException 并且 LinqToCSV 不会读取 CSV 文件的任何行。

4

4 回答 4

3

见这里: http: //www.codeproject.com/Articles/25133/LINQ-to-CSV-library#EnforceCsvColumnAttribute

当为 true 时,Read only 将数据字段读取到具有 [CsvColumn] 属性的公共字段和属性中,忽略所有其他字段和属性。而且,Write 只写入具有 [CsvColumn] 属性的公共字段和属性的内容。

于 2013-12-01T20:47:26.490 回答
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;
                }
            }
        }
    }
于 2014-10-28T04:10:36.460 回答
0

尝试实现 IDataRow 接口——参见“读取原始数据行”

于 2012-09-11T16:45:28.717 回答
0

您需要 IgnoreUnknownColumns http://www.codeproject.com/Articles/25133/LINQ-to-CSV-library#IgnoreUnknownColumns

于 2014-09-21T16:22:38.400 回答