【问题标题】:Map Entity Framework collection to comma delimted string with automapper使用自动映射器将实体框架集合映射到逗号分隔的字符串
【发布时间】:2017-02-02 15:15:09
【问题描述】:

我有一个父类:

public class Parent
{
    ...
    public List<Location> Locations { get; set; }
}

位置类:

public class Location
{
    public int LocationId { get; set; }
    public string Name { get; set; }
}

映射的目标类:

public class Destination
{
    ...
    public string DelimitedLocations { get; set; }
}

我需要使用 automapper 将 LocationId 列表从 Locations 映射到逗号分隔的字符串。

以下是我尝试过的几件事:

CreateMap<Parent, Destination>().ForMember(d => d.DelimitedLocations , o => o.MapFrom(s => string.Join(",", s.Locations.ToList().Select(t => t.LocationID.ToString()))))

结果: LINQ to Entities 无法识别方法 'System.String Join(System.String, System.Collections.Generic.IEnumerable`1[System.String])' 方法,并且此方法无法转换为存储表达式。

下一次尝试:

CreateMap<Parent, Destination>()..ForMember(d => d.TestPlotLocationsSelected, o => o.MapFrom(s => s.TestPlotLocations.ToList().Select(t => string.Join(",", t.TestPlotLocationID.ToString()))))

结果: 类型“System.Collections.Generic.IEnumerable`1[System.String]”上不存在方法“ToString”。

不确定下一步该尝试什么。

【问题讨论】:

  • 它与 AutoMapper 无关——不管有没有它,你都无法在 LINQ to Entities 查询中做你想做的事情。
  • 在您的DelimitedLocationsset; 中,您可以尝试只创建一个StringBuilder 和一个foreach 并最终创建您想要的 - 这可能会容易得多..
  • 感谢您的建议。我最终在映射之外填充了分隔属性。

标签: c# automapper


【解决方案1】:

Select 语句应该类似于

o.Locations.Select(x => x.LocationId).ToList()

演示

public class Program
{
    public static void Main()
    {
        Initialize();

        var source = new Parent
        {
            Locations = new List<Location>
            {
                new Location {LocationId = 1, Name = "One"},
                new Location {LocationId = 2, Name = "Two"},
                new Location {LocationId = 3, Name = "Three"},
            }
        };

        var destination = Mapper.Map<Parent, Destination>(source);

        Console.ReadLine();
    }

    public static void Initialize()
    {
        MapperConfiguration = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<Parent, Destination>()
                .ForMember(dest => dest.DelimitedLocations, mo => mo.MapFrom(src =>
                    src.Locations != null
                        ? string.Join(",", src.Locations.Select(x => x.LocationId).ToList())
                        : ""));
        });
        Mapper = MapperConfiguration.CreateMapper();
    }

    public static IMapper Mapper { get; private set; }

    public static MapperConfiguration MapperConfiguration { get; private set; }
}

public class Parent
{
    public List<Location> Locations { get; set; }
}

public class Location
{
    public int LocationId { get; set; }
    public string Name { get; set; }
}

public class Destination
{
    public string DelimitedLocations { get; set; }
}

结果

【讨论】:

  • 这与我的第一次尝试类似。但是,我的位置列表是一个实体框架集合。 LINQ to Entities 不喜欢 string.Join。请参阅我第一次尝试时收到的错误消息。
  • 是的,我尝试了您的答案,但出现此错误:无法比较类型为 'System.Collections.Generic.ICollection`1[[xxx.xxx.Location, xxx.Web, Version=1.0] 的元素.0.0,文化=中性,PublicKeyToken=null]]'。仅支持原始类型、枚举类型和实体类型。
  • 错误可能不在 AutoMapper 中。您的实体框架甚至在映射之前就可以工作了吗?
  • 你是对的,这不是自动映射器的问题。我只是在尝试使用自动映射器时偶然发现它。当我忽略这个时,我所有的其他映射都在工作。我决定不再花时间试图强制这个映射工作。映射完成后我可以简单地填充。感谢您分享您的想法。
  • 理想情况下,我们在映射之前调用ToList(),以便将结果查询到内存。例如,_dbContext.Parent.Include("Location").ToList()
猜你喜欢
  • 2018-03-01
  • 2014-01-14
  • 2018-07-20
  • 1970-01-01
  • 2017-09-20
  • 1970-01-01
  • 2011-11-18
  • 2023-03-10
  • 2010-09-24
相关资源
最近更新 更多