英文:
CsvHelper return null values for complex types if all properties are null
问题
我正在使用CsvHelper 12.1.2来读取CSV文件中的复杂对象及其子对象,并且遇到的问题是,如果子对象的所有字段都为null,我希望整个实体也为null。
以下是我有的内容:
Worker
Name
Age
PhoneNumber
AreaCode
Prefix
LineNumber
如果AreaCode + Prefix + LineNumber都为null,那么我希望PhoneNumber也为null。
以下是我使用的部分代码:
public class WorkerModelMap : ClassMap<Worker>
{
// 这里是映射Worker对象的部分代码,包括PhoneNumber和子对象的映射
}
public class HomePhoneNumberModelMap : ClassMap<PhoneNumber>
{
// 这里是映射HomePhoneNumber对象的部分代码
}
我不确定这是否是映射器的问题,还是配置设置的问题,但任何帮助都会感激。我知道这是可能的,因为我几天前已经使其工作,但不知何故丢失了那些更改!谢谢!
英文:
I'm mapping a complex object with child object's in a CSV file and I'm using CsvHelper 12.1.2 to read it in. The issue I'm having is that if ALL fields for a child object are null I would like the entire entity to be null.
Here's what I have:
Worker
Name
Age
PhoneNumber
AreaCode
Prefix
LineNumber
If AreaCode + Prefix + LineNumber is null then I want PhoneNumber to be null.
Here's a partial of the code I'm using:
public class WorkerModelMap : ClassMap<Worker>
{
public WorkerModelMap()
{
Map(x => x.VoterId).Name("VoterId");
Map(x => x.FirstName).Name("FirstName");
Map(x => x.MiddleName).Name("MiddleName");
Map(x => x.LastName).Name("LastName");
Map(x => x.Suffix).Name("Suffix");
Map(x => x.Email).Name("Email");
Map(x => x.Party).Name("Party");
Map(x => x.DateOfBirth).Optional().Name("DateOfBirth").ConvertUsing(row => NodaTimeExtensions.ConvertStringToLocalDate(row.GetField("DateOfBirth")));
Map(x => x.Status).Name("Status").ConvertUsing(row =>
{
if (!int.TryParse(row.GetField("Status"), out int status) || !Enum.IsDefined(typeof(WorkerStatus), status))
{
// Unknown is the default
return WorkerStatus.Unknown;
}
return (WorkerStatus)Enum.Parse(typeof(WorkerStatus), row.GetField("Status"));
});
Map(x => x.Type).Name("WorkerType").ConvertUsing(row =>
{
if (!int.TryParse(row.GetField("WorkerType"), out int type) || !Enum.IsDefined(typeof(WorkerType), type))
{
// Unknown is the default
return WorkerType.Unknown;
}
return (WorkerType)Enum.Parse(typeof(WorkerType), row.GetField("WorkerType"));
});
Map(x => x.IsProtected).Name("IsProtected").ConvertUsing(row =>
{
if (row.GetField("IsProtected") == "Y")
{
return true;
}
return false;
});
References<HomePhoneNumberModelMap>(x => x.Phone);
References<BusinessPhoneNumberModelMap>(x => x.BusinessTelephone);
References<MobilePhoneNumberModelMap>(x => x.MobileTelephone);
References<ResidentialAddressModelMap>(x => x.ResidentialAddress);
References<PaymentAddressModelMap>(x => x.PaymentAddress);
}
}
public class HomePhoneNumberModelMap : ClassMap<PhoneNumber>
{
public HomePhoneNumberModelMap()
{
Map(x => x.AreaCode).Name("HomeAreaCode");
Map(x => x.Prefix).Name("HomePrefix");
Map(x => x.LineNumber).Name("HomeLineNumber");
}
}
I'm not sure if it's a mapper issue or if there's a configuration setting, but any help is appreciated. I know this IS possible as I had it working a few days ago but somehow lost those changes!! Thanks!
答案1
得分: 2
我找到了一个解决方案。最终,我将“References”替换为“ConvertUsing”:
Map(m => m.Phone).ConvertUsing(NullPhoneNumberParser);
public PhoneNumber NullPhoneNumberParser(IReaderRow row)
{
var rawAreaCode = row.GetField<string>(row.Context.CurrentIndex + 1);
var rawPrefix = row.GetField<string>(row.Context.CurrentIndex + 1);
var rawLineNumber = row.GetField<string>(row.Context.CurrentIndex + 1);
if (string.IsNullOrWhiteSpace(rawAreaCode) && string.IsNullOrWhiteSpace(rawPrefix) && string.IsNullOrWhiteSpace(rawLineNumber))
{
return null;
}
return new PhoneNumber()
{
AreaCode = rawAreaCode,
Prefix = rawPrefix,
LineNumber = rawLineNumber,
};
}
英文:
I found a solution. I ended up swapping "References" for "ConvertUsing":
Map(m => m.Phone).ConvertUsing(NullPhoneNumberParser);
public PhoneNumber NullPhoneNumberParser(IReaderRow row)
{
var rawAreaCode = row.GetField<string>(row.Context.CurrentIndex + 1);
var rawPrefix = row.GetField<string>(row.Context.CurrentIndex + 1);
var rawLineNumber = row.GetField<string>(row.Context.CurrentIndex + 1);
if (string.IsNullOrWhiteSpace(rawAreaCode) && string.IsNullOrWhiteSpace(rawPrefix) && string.IsNullOrWhiteSpace(rawLineNumber))
{
return null;
}
return new PhoneNumber()
{
AreaCode = rawAreaCode,
Prefix = rawPrefix,
LineNumber = rawLineNumber,
};
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论