.net 使用AutoMapper将数据列表展开为嵌套列表

bvhaajcl  于 2022-11-26  发布在  .NET
关注(0)|答案(1)|浏览(146)

我有一个平面化的数据列表(县和市),我想Map到一个非平面化的(县和市)嵌套属性列表(州.县)。请检查以下.NET 6.0控制台应用程序代码:

using AutoMapper;

public class CountyAndCity
{
    public int CountyId { get; set; }
    public string CountyName { get; set; }
    public int CityId { get; set; }
    public string CityName { get; set; }
    public int CityPopulation { get; set; }
}

public class City
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Population { get; set; }
}

public class County
{
    public int Id { get; set; }
    public string Name { get; set; }
    public IEnumerable<City> Cities { get; set; }
}

public class State
{
    public List<County> Counties { get; set; }
}

public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<CountyAndCity, City>()
            .ForMember(destination => destination.Id, options => options.MapFrom(source => source.CountyId))
            .ForMember(destination => destination.Name, options => options.MapFrom(source => source.CountyName))
            .ForMember(destination => destination.Population, options => options.MapFrom(source => source.CityPopulation));

        CreateMap<IEnumerable<CountyAndCity>, County>()
            .ForMember(destination => destination.Id, options => options.MapFrom(source => source.FirstOrDefault().CountyId))
            .ForMember(destination => destination.Name, options => options.MapFrom(source => source.FirstOrDefault().CountyName))
            .ForMember(destination => destination.Cities, options => options.MapFrom(source => source));

        CreateMap<IEnumerable<CountyAndCity>, State>()
            .ForMember(destination => destination.Counties, options => options.MapFrom(source => source));
    }
}

class HelloWorld
{
    static void Main()
    {
        var flattenData = new List<CountyAndCity>
        {
            new CountyAndCity { CountyId = 1, CountyName = "Albany", CityId = 10, CityName = "Cohoes", CityPopulation = 1000 },
            new CountyAndCity { CountyId = 1, CountyName = "Albany", CityId = 20, CityName = "Watervliet", CityPopulation = 1000 },
            new CountyAndCity { CountyId = 2, CountyName = "Bronx", CityId = 30, CityName = "Wakefield", CityPopulation = 2000 },
            new CountyAndCity { CountyId = 2, CountyName = "Bronx", CityId = 40, CityName = "Eastchester", CityPopulation = 2000 },
        };

        var unflattenData = new List<County>
        {
            new County { Id = 1, Name = "Albany", Cities = new List<City>
            {
                new City { Id = 10, Name = "Cohoes", Population = 1000 },
                new City { Id = 20, Name = "Watervliet", Population = 1000 },
            }},
            new County { Id = 2, Name = "Bronx", Cities = new List<City>
            {
                new City { Id = 30, Name = "Wakefield", Population = 2000 },
                new City { Id = 40, Name = "Eastchester", Population = 2000 },
            }},
        };

        var mapperConfiguration = new MapperConfiguration(configuration => configuration.AddProfile(new AutoMapperProfile()));
        var mapper = mapperConfiguration.CreateMapper();
        State mappedData = mapper.Map<State>(flattenData);
        //Should be TRUE after some kind of custom comparison but it is goof enough for the example.
        bool result = mappedData.Counties == unflattenData;
    }
}

我收到以下异常:

/*
Error mapping types.

Mapping types:
IEnumerable`1 -> State
System.Collections.Generic.IEnumerable`1[[CountyAndCity, ConsoleApp1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] -> State

Type Map configuration:
IEnumerable`1 -> State
System.Collections.Generic.IEnumerable`1[[CountyAndCity, ConsoleApp1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] -> State

Destination Member:
Counties
*/

我做错了什么?我应该创建什么Map器来将unflatten列表转换为flatten nested属性:“县”?

dxxyhpgq

dxxyhpgq1#

您可以寻找Custom Value Resolver来群组County的数据。
第一个
Demo @ .NET Fiddle
而用下面的语句:

bool result = mappedData.Counties == unflattenData;

当比较两个列表时,你仍然会得到false(即使两个列表的内容是相同的),因为引用被用来比较,而不是两个列表的 * content *:
相反,您需要重写Equals()GetHashCode()方法。

public class City
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Population { get; set; }
    
    
    public override bool Equals (Object obj)
    {
        if (obj is not City)
            return false;
        
        City b = (City)obj;
        
        return Id == b.Id
            && Name == b.Name
            && Population == b.Population;
    }
    
    
    public override int GetHashCode()
    {
        return this.Id.GetHashCode() ^ this.Name.GetHashCode() ^ this.Population.GetHashCode(); 
    }
}

public class County
{
    public int Id { get; set; }
    public string Name { get; set; }
    public IEnumerable<City> Cities { get; set; }
    
    
    public override bool Equals (Object obj)
    {
        if (obj is not County)
            return false;
        
        County b = (County)obj;
        
        return Id == b.Id
            && Name == b.Name
            && Enumerable.SequenceEqual(Cities, b.Cities);
    }
    
    
    public override int GetHashCode()
    {
        return this.Id.GetHashCode() ^ this.Name.GetHashCode(); 
    }
}

并使用Enumerable.SequenceEqual()方法比较列表的内容。

bool result = Enumerable.SequenceEqual(mappedData.Counties, unflattenData);

相关问题