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!
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,
};
}