C# 自动映射和处理空属性

C# 自动映射和处理空属性,c#,linq,automapper,C#,Linq,Automapper,我已按如下方式设置映射: CreateMap<SourceClass, DestinationClass>().ForMember(destinationMember => destinationMember.Provider, memberOptions => memberOptions.MapFrom(src => src.Providers.FirstOrDefault())); CreateMap().formMember(

我已按如下方式设置映射:

CreateMap<SourceClass, DestinationClass>().ForMember(destinationMember => destinationMember.Provider,
                memberOptions => memberOptions.MapFrom(src => src.Providers.FirstOrDefault()));
CreateMap().formMember(destinationMember=>destinationMember.Provider,
memberOptions=>memberOptions.MapFrom(src=>src.Providers.FirstOrDefault());
我从SourceClass中的列表映射到目标类中的字符串

我的问题是,如何处理“提供者”为空的情况

我试过使用:

src?.Providers?.FirstOrDefault()

但是我得到一个错误,说我不能在lambda中使用null传播子

我一直在阅读Automapper,仍然不确定am是否自动处理空案例。我试图构建表达式树,但看不到提供其他信息的任何信息

如果有帮助的话,我正在使用AutomapperV6.1.1。

您可以尝试使用带有automapper的。可能看起来像这样

public class ListFormatter : IValueConverter<string, List<string>>
{
  public List<string> Convert(string source)
  {
    if (source != null)
    {
      return new List<string> { source };
    }
    return new List<string>();
  }
}
CreateMap<SourceClass, DestinationClass>()
  .ForMember(destinationMember => destinationMember.Provider,
             memberOptions => memberOptions.ConvertUsing(new ListFormatter()));
公共类ListFormatter:IValueConverter
{
公共列表转换(字符串源)
{
如果(源!=null)
{
返回新列表{source};
}
返回新列表();
}
}
然后你可以像这样使用它

public class ListFormatter : IValueConverter<string, List<string>>
{
  public List<string> Convert(string source)
  {
    if (source != null)
    {
      return new List<string> { source };
    }
    return new List<string>();
  }
}
CreateMap<SourceClass, DestinationClass>()
  .ForMember(destinationMember => destinationMember.Provider,
             memberOptions => memberOptions.ConvertUsing(new ListFormatter()));
CreateMap()
.FormMember(destinationMember=>destinationMember.Provider,
memberOptions=>memberOptions.ConvertUsing(新的ListFormatter());
如果您需要切换逻辑或执行更复杂的操作,这将允许您在将来更改值转换器

编辑

因为您使用的是较旧的版本,所以可以使用private/static/extension方法来完成相同的工作。大概是

List<string> ConvertStringToList(string source)
{
  if (source != null)
  {
    return new List<string> { source };
  }
  return new List<string>();
}
列表转换字符串列表(字符串源)
{
如果(源!=null)
{
返回新列表{source};
}
返回新列表();
}
然后就这么说吧

CreateMap<SourceClass, DestinationClass>()
  .ForMember(destinationMember => destinationMember.Provider,
             memberOptions => memberOptions.MapFrom(src => ConvertStringToList(src.Provider)));
CreateMap()
.FormMember(destinationMember=>destinationMember.Provider,
memberOptions=>memberOptions.MapFrom(src=>ConvertStringToList(src.Provider));
随着事情变得越来越复杂,我通常更喜欢这样做,而不是做一些内联的事情,为了可读性,您可以尝试使用带有AutoMapper的。可能看起来像这样

public class ListFormatter : IValueConverter<string, List<string>>
{
  public List<string> Convert(string source)
  {
    if (source != null)
    {
      return new List<string> { source };
    }
    return new List<string>();
  }
}
CreateMap<SourceClass, DestinationClass>()
  .ForMember(destinationMember => destinationMember.Provider,
             memberOptions => memberOptions.ConvertUsing(new ListFormatter()));
公共类ListFormatter:IValueConverter
{
公共列表转换(字符串源)
{
如果(源!=null)
{
返回新列表{source};
}
返回新列表();
}
}
然后你可以像这样使用它

public class ListFormatter : IValueConverter<string, List<string>>
{
  public List<string> Convert(string source)
  {
    if (source != null)
    {
      return new List<string> { source };
    }
    return new List<string>();
  }
}
CreateMap<SourceClass, DestinationClass>()
  .ForMember(destinationMember => destinationMember.Provider,
             memberOptions => memberOptions.ConvertUsing(new ListFormatter()));
CreateMap()
.FormMember(destinationMember=>destinationMember.Provider,
memberOptions=>memberOptions.ConvertUsing(新的ListFormatter());
如果您需要切换逻辑或执行更复杂的操作,这将允许您在将来更改值转换器

编辑

因为您使用的是较旧的版本,所以可以使用private/static/extension方法来完成相同的工作。大概是

List<string> ConvertStringToList(string source)
{
  if (source != null)
  {
    return new List<string> { source };
  }
  return new List<string>();
}
列表转换字符串列表(字符串源)
{
如果(源!=null)
{
返回新列表{source};
}
返回新列表();
}
然后就这么说吧

CreateMap<SourceClass, DestinationClass>()
  .ForMember(destinationMember => destinationMember.Provider,
             memberOptions => memberOptions.MapFrom(src => ConvertStringToList(src.Provider)));
CreateMap()
.FormMember(destinationMember=>destinationMember.Provider,
memberOptions=>memberOptions.MapFrom(src=>ConvertStringToList(src.Provider));

我通常更喜欢这样做,而不是在事情变得更复杂时进行内联操作,为了可读性,请尝试使用AutoMapper中的NullSubstitution选项
您可以从AutoMapper中读取并尝试使用NullSubstitution选项
您可以阅读

当然您可以编写一些单元测试来看看会发生什么。@LucianBargaoanu您是对的,我现在就这么做现在无法测试,但您可以尝试
src?.Providers?.FirstOrDefault()??“”
。如果继续进行的表达式
的计算结果为null,则将值设置为空字符串。@TylerHundley,因此我添加了一个单元测试,如果提供程序为null,则映射为null。你知道我怎样才能把一个空列表映射到一个空列表吗?到目前为止,我相信它正在将一个空列表映射为null(因为FirstOrDefault),您的意思是将一个空列表映射为一个空字符串吗?是否将空列表转换为空字符串?你试过我上一篇评论中的代码了吗?当然你可以写一些单元测试来看看会发生什么。@LucianBargaoanu你是对的,我现在就这么做现在无法测试,但你可以尝试
src?.Providers?.FirstOrDefault()??“”
。如果继续进行的表达式
的计算结果为null,则将值设置为空字符串。@TylerHundley,因此我添加了一个单元测试,如果提供程序为null,则映射为null。你知道我怎样才能把一个空列表映射到一个空列表吗?到目前为止,我相信它正在将一个空列表映射为null(因为FirstOrDefault),您的意思是将一个空列表映射为一个空字符串吗?是否将空列表转换为空字符串?你试过我之前评论中的代码了吗?啊,我说得太快了,似乎我们正在使用的automapper版本不支持ValueConverter。我还注意到你问了另一个问题。回顾一下这里的评论,我不知道你问的是源到目标还是目标到源的转换。啊,我说得太快了,似乎我们使用的automapper版本不支持ValueConverters。我还注意到你问了另一个问题。回顾这里的评论,我不知道你是在问源到目标还是目标到源的转换。