Search code examples
csvhelper

Conditionally Ignore reference mapping


Is it possible to programatically/dynamically ignore a reference mapping if it satisfies a certain condition?

Consider the following structure

public class SkuDto
{
    public string Name;
    public InnerSkuDto InnerSku;
}

public class InnerSkuDto
{
    public Guid SkuNumber;
}

public sealed class SkuMap : ClassMap<SkuDto>
{
    Map(m => m.Name);
    References<InnerSkuMap>(m => m.InnerSku);
}

public sealed class InnerSkuMap : ClassMap<InnerSkuDto> { ... }

Now sometimes the InnerSku property in the SkuDto object can be null in which case the resulting CSV output contains 00000000-0000-0000-0000-000000000000 for the SkuNumber instead of an empty cell. So is it possible to ignore the InnerSku if its null?


Solution

  • A Guid can't be null, so it defaults to an empty Guid, which you see in the CSV output. One solution is to change SkuNumber to a nullable Guid

    public class InnerSkuDto
    {
        public Guid? SkuNumber;
    }
    

    If you can't or don't want to change SkuNumber to a nullable Guid, the other option is to use a custom converter. Here I override the ConvertToString method of GuidConverter.

    public class EmptyGuidConverter : GuidConverter
    {
        public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
        {
            if ((Guid)value == Guid.Empty)
            {
                return string.Empty;
            }
    
            return base.ConvertToString(value, row, memberMapData);
        }
    }
    
    public sealed class InnerSkuMap : ClassMap<InnerSkuDto>
    {
        public InnerSkuMap()
        {
            Map(m => m.SkuNumber).TypeConverter<EmptyGuidConverter>();
        }
    }
    

    Or instead of registering the converter for a single property, you can register it with your CsvWriter for all Guid values. Just make sure to add it before registering your ClassMap.

    csv.Configuration.TypeConverterCache.AddConverter<Guid>(new EmptyGuidConverter());