自定义 CsvClassMap 中的 CsvClassMap

CsvClassMap inside a custom CsvClassMap

我正在使用 CsvHelper。为了在我的对象和 CSV 文件之间执行映射,我使用 CsvClassMap。我映射到自身的 class 包含其他 classes。目前,为了执行到内部 classes 的映射,我在 CsvPropertyMap 上使用 ConvertUsing。下面的一个例子。 Car 是我的主要对象,它包含 Engine 并且引擎在单独的方法中解析:

public sealed class CarMapping : CsvClassMap<Car>
{
    CarMapping()
    {
        Map(m => m.Id).Name("CarId");
        Map(m => m.Color).Name("CarColor");
        Map(m => m.YearOfProduction).Name("YearOfProduction");
        Map(m => m.Engine).ConvertUsing(ParseEngine);
    }

    private Engine ParseEngine(ICsvReaderRow row)
    {
        var year = row.GetField<int>("EngineYear");
        var cc = row.GetField<int>("EngineCC");

        return new Engine() 
        {
            Year = year,
            CC = cc,
        };
    }
}

这行得通。但我想要实现的是在另一个映射中使用一个映射。类似于下面的(假设的解决方案):

public sealed class EngineMapping : CsvClassMap<Engine>
{
    EngineMapping()
    {
        Map(m => m.Year).Name("EngineYear");
        Map(m => m.Cc).Name("EngineCC");
    }
}

然后在CarMapping里面使用EngineMapping:

public sealed class CarMapping : CsvClassMap<Car>
{
    CarMapping()
    {
        Map(m => m.Id).Name("CarId");
        Map(m => m.Color).Name("CarColor");
        Map(m => m.YearOfProduction).Name("YearOfProduction");

        // Not real code. Something I would like to be able to use.
        // Use a mapping inside the current mapping
        Map(m => m.Engine).ConsumeClassMap<EngineMapping>();
    }
}

这种映射在 json 格式上更自然,使用 Json.net 您可以使用 JsonConvert.SerializeObject(Object) 将对象转换为 json 格式并使用 JsonConvert.DeserializeObject<T>(String); 从 Json 返回到您的对象。

举个例子:

Product product = new Product();
product.Name = "Apple";
product.ExpiryDate = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };

string output = JsonConvert.SerializeObject(product);
//{
//  "Name": "Apple",
//  "ExpiryDate": "2008-12-28T00:00:00",
//  "Price": 3.99,
//  "Sizes": [
//    "Small",
//    "Medium",
//    "Large"
//  ]
//}

Product deserializedProduct = JsonConvert.DeserializeObject<Product>(output);

我知道这不是你想要的答案,但太长了无法作为评论(而且我没有足够的声誉来发表评论)。

你想要的在CSVHelper中称为Reference地图。

...
CarMap()
{
    Map(m => m.Id).Name("CarId");
    Map(m => m.Color).Name("CarColor");
    Map(m => m.YearOfProduction).Name("YearOfProduction");
    References<EngineMap>(m => m.Engine);

    // or if you tuck it away in the Engine class:
    //References<Engine.EngineMap>(m => m.Engine);
}

然后您在 Engine class 的新地图中拥有其余部分,就像您在 post:

中拥有它一样
EngineMap()
{
    Map(m => m.Year).Name("EngineYear");
    Map(m => m.Cc).Name("EngineCC");
}

如果 CSV 没有 header,那么您使用的是索引,所使用的索引可能是 28,因为您仍在引用相同的顺序CSV.