Я пытаюсь сопоставить DTO с сущностями с помощью AutoMapper в. Net Базовом приложении, которое использует Entity Framework.
Всякий раз, когда я пытаюсь отобразить коллекции, у меня возникает следующее исключение:
Unable to cast object of type 'System.Collections.Generic.HashSet`1[TDestination]' to type 'System.Collections.Generic.IList`1[TDestination]'
Это происходит, когда я пытаюсь обновить существующую сущность следующим образом:
mapper.Map(source, destination);
Это происходит потому, что в объекте IEnumerable имеется коллекция в свойстве. Это свойство инициализируется для HashSet Entity Framework в целевом объекте и для List десериализатором JSON в исходном объекте.
Я нашел несколько проблем на GitHub, касающихся моей проблемы, однако упомянутое решение не работает для меня:
https://github.com/AutoMapper/AutoMapper/issues/2397
https://github.com/AutoMapper/AutoMapper/issues/2435
https://github.com/AutoMapper/AutoMapper/issues/2436
https://github.com/AutoMapper/AutoMapper/issues/2447
Решение, упомянутое в вышеуказанных вопросах должен использовать UseDestinationValue
на элементе назначения при настройке сопоставления.
Вот минимальный пример, иллюстрирующий мою проблему:
AMTest.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Automapper" Version="9.0.0" />
<PackageReference Include="Automapper.Collection" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.2.0" />
</ItemGroup>
</Project>
AMTest.cs
using System.Collections.Generic;
using AutoMapper;
using AutoMapper.EquivalencyExpression;
using Xunit;
namespace AMTest
{
public class SourceItem
{
public int Id { get; set; }
}
public class Source
{
public IEnumerable<SourceItem> Items { get; set; }
}
public class DestinationItem
{
public int Id { get; set; }
}
public class Destination
{
public IEnumerable<DestinationItem> Items { get; set; }
}
public class UnitTest1
{
[Fact]
public void Test1()
{
var config = new MapperConfiguration(cfg =>
{
cfg.AddCollectionMappers();
cfg.CreateMap<SourceItem, DestinationItem>()
.EqualityComparison((s, d) => s.Id == d.Id);
cfg.CreateMap<Source, Destination>()
.ForMember(d => d.Items, o => o.UseDestinationValue());
});
var mapper = new Mapper(config);
var src = new Source
{
Items = new List<SourceItem>(),
};
var dest = new Destination
{
Items = new HashSet<DestinationItem>(),
};
mapper.Map(src, dest);
}
}
}
В соответствии с обнаруженными в сети проблемами GitHub эта настройка должна работать, но не работает.
Может Вы помогаете мне понять, почему?