CSVHelper - 将名称从 CSV 导入到具有相同名称的对象 属性

CSVHelper - import convert name from CSV to object with equal name property

我正在使用 CSVHelper 将一行导入到以下 class:

public class RequestMonitoring
{
    public string PNdsPn { get; set; }

    [Required]
    public virtual Stamp PUsrCrStatus { get; set; } 
    
    // many other properties
} 

Stamp 看起来像这样:

public class Stamp
{
    public int Weight { get; set; }

    [Required]
    public string MachineName { get; set; }  
    
    // many other properties
}

CSV 如下所示:

$P_NDS_PN;#P_USR_CR_Staus; ...
CTD_037453;SYS complete; ...

其中“SYS complete”是标记的“MachineName”。

但是类型转换没有像我预期的那样工作。如果我使用的是 CustomTypeConverter,它不会触发它的 ConvertFromString 方法,除非我将“PUsrCrStatus”属性 更改为键入字符串,这在我看来毫无意义。

所以我尝试使用 ConvertUsing 进行内联转换,如下所示:

classMap.Map(requestMonitoring => requestMonitoring.PUsrCrStatus)
.ConvertUsing(row = > _context.Stamps.SingleOrDefault(stamp => stamp.MachineName == row.GetField("#P_USR_CR_Status"));

但这只有在我将 [Ignore] 属性放在 Stamp 模型中除“MachineName”之外的每个属性上时才有效,如果以后想从不同的 CSV 导入 Stamps,这是不好的。

所以我尝试在 classmap 中定义这些忽略,例如:

classMap.Map(requestMonitoring => requestMonitoring.PUsrCrStatus.Weight).Ignore();

也尝试过:

classMap.Map(typeof(Stamp),typeof(Stamp).GetProperties().SingleOrDefault(p => p.Name == "Id") ).Ignore();

但它们都不起作用,它仍然告诉我 CSV 中没有名称为“Weight”的列。

谁能帮我解决这个问题? 提前致谢

我可能明白你想做什么。如果您要在 Stamp class 中映射的唯一字段是 MachineName,您可能需要重新考虑您在其他问题中遇到的 var classMap = csv.Configuration.AutoMap<RequestMonitoring>();AutoMap 正在映射 PUsrCrStatus 的所有属性。看看这是否能让您更接近您想要做的事情。

static void Main(string[] args)
{
    using (var stream = new MemoryStream())
    using (var writer = new StreamWriter(stream))
    using (var reader = new StreamReader(stream))
    using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
    {
        writer.WriteLine("$P_NDS_PN,#P_USR_CR_Status");
        writer.WriteLine("test,StampName");
        writer.Flush();
        stream.Position = 0;

        var classMap = new DefaultClassMap<RequestMonitoring>();

        foreach (var property in typeof(RequestMonitoring).GetProperties())
        {
            if (property.Name == "PUsrCrStatus") { continue; }
            var columnName = property.Name switch
            {
                "PNdsPn" => "$P_NDS_PN",
                { } x when x.StartsWith("PUsrCr") => property.Name.Replace("PUsrCr", "#P_USR_CR_"),
                _ => property.Name
            };
            classMap.Map(typeof(RequestMonitoring), property).Name(columnName);
        }

        classMap.Map(requestMonitoring => requestMonitoring.PUsrCrStatus.MachineName).Name("#P_USR_CR_Status");

        csv.Configuration.RegisterClassMap(classMap);

        var records = csv.GetRecords<RequestMonitoring>().ToList();
    }
}

或者您可以使用自定义 TypeConverter 映射 PUsrCrStatus

static void Main(string[] args)
{
    using (var stream = new MemoryStream())
    using (var writer = new StreamWriter(stream))
    using (var reader = new StreamReader(stream))
    using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
    {
        writer.WriteLine("$P_NDS_PN,#P_USR_CR_Status");
        writer.WriteLine("test,StampName");
        writer.Flush();
        stream.Position = 0;

        var classMap = new DefaultClassMap<RequestMonitoring>();

        foreach (var property in typeof(RequestMonitoring).GetProperties())
        {
            var columnName = property.Name switch
            {
                "PNdsPn" => "$P_NDS_PN",
                { } x when x.StartsWith("PUsrCr") => property.Name.Replace("PUsrCr", "#P_USR_CR_"),
                _ => property.Name
            };
            classMap.Map(typeof(RequestMonitoring), property).Name(columnName);
        }

        classMap.Map(requestMonitoring => requestMonitoring.PUsrCrStatus).TypeConverter<StampTypeConverter>();

        csv.Configuration.RegisterClassMap(classMap);

        var records = csv.GetRecords<RequestMonitoring>().ToList();
    }
}

public class StampTypeConverter : DefaultTypeConverter
{
    public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        return new Stamp { MachineName = text };
    }
}