【问题标题】:No properties are mapped for type using csvHelper没有使用 csvHelper 映射类型的属性
【发布时间】:2020-06-22 03:01:04
【问题描述】:

我有两种方法可以返回 EmployeeCsv 和 CardCsv 列表。

public class EmployeeCsv
{
    public string EmployeeId { get; set; }
    public string EmployeeName { get; set; }
}

public class CardCsv
{
    public string MaxCharge { get; set; }
    public string MaxDiscount { get; set; }
}

public List<EmployeeCsv> GetEmployeeList() {} // returns list of EmployeeCsv
public List<CardCsv> GetCardList() {} // returns list of CardCsv

我想为这两种方法声明一个类型列表。 所以我像下面这样改变了它们

public interface ITest {}
public class EmployeeCsv : ITest
{
    public string EmployeeId { get; set; }
    public string EmployeeName { get; set; }
}

public class CardCsv : ITest
{
    public string MaxCharge { get; set; }
    public string MaxDiscount { get; set; }
}

public List<ITest> GetEmployeeList() {}
public List<ITest> GetCardList() {}

主要:

void main()
{
    var records = new List<ITest>();
    records = GetEmployeeList();
    using (var writer = new StreamWriter(fileName))
    using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
    {
        csv.Configuration.ShouldQuote = (field, context) => true;
        csv.WriteRecords(records); // error here
    }
}

在向这两个类添加接口后保存时出现错误。 我该如何解决这个问题?

【问题讨论】:

  • 您没有因为任何特殊原因告诉我们错误信息吗?对大多数人来说,错误消息很有用
  • 主题是错误信息。 CsvHelper.WriterException: '没有为类型 'ProjectName.ITest' 映射任何属性。'
  • CsvHelper 抱怨您的类型没有在 ITest 上找到的列名称的属性。发布您的 csv 布局,它可能会有所帮助。大多数情况下,CSV 应该具有固定的列,因此您通过 ITest 组合两个 csv 的意图似乎令人困惑。
  • 这就是 ITest 布局的全部内容。没有其他的。我添加它是因为我只想删除一种类型 List().

标签: c# csvhelper


【解决方案1】:

这里的问题是CsvHelper 不知道列表项的实例。您是在告诉它处理 ITest 项目。

考虑以下几点:

var records = new List<ITest> { new EmployeeCsv(), new CardCsv() };

这是有效的代码。现在把自己放在 CsvHelper 的位置上。它将如何从项目中创建 CSV?它会将它们处理为Employee 还是Card?两者都不。它只知道这些项目是ITest(一个空白界面)。因此你的错误。

与其使用ITest 使其复杂化,不如将列表项保留为其具体类型,但将它们视为IEnumerable

// Leave them as the derived types
public List<EmployeeCsv> GetEmployeeList() { .. }
public List<CardCsv> GetCardList() { .. }

void Main() {
    // Notice the IEnumerable so we can reuse WriteToFile()
    IEnumerable items = GetEmployeeList();
    WriteToFile(items); // employees

    items = GetCardList();
    WriteToFile(items); // cards
}
void WriteToFile(IEnumerable records) {
    ...
    csv.WriteRecords(records);
}

这样,CsvHelper 可以实际检查列表并找出类型,而不会出现 ITest 混淆。

编辑: 您可能应该创建一个通用方法,这样您可以将您的项目限制为ITest,如果您真的愿意,或者您可以将其保持打开状态。

// This needs to stay as its concrete type.
public List<EmployeeCsv> GetEmployeeList() { .. }

void Main() { 
    WriteToFile(GetEmployeeList()); 
}

// Get rid of the 'where' to make it accept things other than ITest.
void WriteToFile<T>(IEnumerable<T> records) where T : ITest
{   ...
    csv.WriteRecords(records);
}

【讨论】:

  • 感谢您的回答。我也删除了界面。但是我通过将记录设为 List 并使所有方法返回 List. 找到了解决方案
  • 在我的编辑中仍然值得考虑通用版本,因为这将使您能够强输入列表(并限制方法)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-23
  • 2023-03-25
相关资源
最近更新 更多