CsvHelper 如果所有属性都为 null,则返回复杂类型的 null 值。

huangapple go评论69阅读模式
英文:

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&lt;Worker&gt;
{
    public WorkerModelMap()
    {
        Map(x =&gt; x.VoterId).Name(&quot;VoterId&quot;);
        Map(x =&gt; x.FirstName).Name(&quot;FirstName&quot;);
        Map(x =&gt; x.MiddleName).Name(&quot;MiddleName&quot;);
        Map(x =&gt; x.LastName).Name(&quot;LastName&quot;);
        Map(x =&gt; x.Suffix).Name(&quot;Suffix&quot;);
        Map(x =&gt; x.Email).Name(&quot;Email&quot;);
        Map(x =&gt; x.Party).Name(&quot;Party&quot;);
        Map(x =&gt; x.DateOfBirth).Optional().Name(&quot;DateOfBirth&quot;).ConvertUsing(row =&gt; NodaTimeExtensions.ConvertStringToLocalDate(row.GetField(&quot;DateOfBirth&quot;)));
        Map(x =&gt; x.Status).Name(&quot;Status&quot;).ConvertUsing(row =&gt;
        {
            if (!int.TryParse(row.GetField(&quot;Status&quot;), out int status) || !Enum.IsDefined(typeof(WorkerStatus), status))
            {
                // Unknown is the default
                return WorkerStatus.Unknown;
            }

            return (WorkerStatus)Enum.Parse(typeof(WorkerStatus), row.GetField(&quot;Status&quot;));
        });

        Map(x =&gt; x.Type).Name(&quot;WorkerType&quot;).ConvertUsing(row =&gt;
        {
            if (!int.TryParse(row.GetField(&quot;WorkerType&quot;), out int type) || !Enum.IsDefined(typeof(WorkerType), type))
            {
                // Unknown is the default
                return WorkerType.Unknown;
            }

            return (WorkerType)Enum.Parse(typeof(WorkerType), row.GetField(&quot;WorkerType&quot;));
        });

        Map(x =&gt; x.IsProtected).Name(&quot;IsProtected&quot;).ConvertUsing(row =&gt;
        {
            if (row.GetField(&quot;IsProtected&quot;) == &quot;Y&quot;)
            {
                return true;
            }

            return false;
        });
            
        References&lt;HomePhoneNumberModelMap&gt;(x =&gt; x.Phone);
        References&lt;BusinessPhoneNumberModelMap&gt;(x =&gt; x.BusinessTelephone);
        References&lt;MobilePhoneNumberModelMap&gt;(x =&gt; x.MobileTelephone);
        References&lt;ResidentialAddressModelMap&gt;(x =&gt; x.ResidentialAddress);
        References&lt;PaymentAddressModelMap&gt;(x =&gt; x.PaymentAddress);
    }
}

public class HomePhoneNumberModelMap : ClassMap&lt;PhoneNumber&gt;
{
    public HomePhoneNumberModelMap() 
    {
        Map(x =&gt; x.AreaCode).Name(&quot;HomeAreaCode&quot;);
        Map(x =&gt; x.Prefix).Name(&quot;HomePrefix&quot;);
        Map(x =&gt; x.LineNumber).Name(&quot;HomeLineNumber&quot;);
    }
}

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 =&gt; m.Phone).ConvertUsing(NullPhoneNumberParser);

public PhoneNumber NullPhoneNumberParser(IReaderRow row)
{
    var rawAreaCode = row.GetField&lt;string&gt;(row.Context.CurrentIndex + 1);
    var rawPrefix = row.GetField&lt;string&gt;(row.Context.CurrentIndex + 1);
    var rawLineNumber = row.GetField&lt;string&gt;(row.Context.CurrentIndex + 1);

    if (string.IsNullOrWhiteSpace(rawAreaCode) &amp;&amp; string.IsNullOrWhiteSpace(rawPrefix) &amp;&amp; string.IsNullOrWhiteSpace(rawLineNumber))
    {
        return null;
    }

    return new PhoneNumber()
    {
        AreaCode = rawAreaCode,
        Prefix = rawPrefix,
        LineNumber = rawLineNumber,
    };
}

huangapple
  • 本文由 发表于 2023年6月21日 23:02:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76524702.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定