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 };
}
}
我正在使用 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 };
}
}