我正在尝试使用Map
将ReverseMap
和ImmutableHashSet
的ICollection
属性赋予AutoMapper
。
自动映射器已成功将ImmutableHashSet
属性映射到ICollection
,但无法将ICollection
映射回ImmutableHashSet
这是最小的可复制示例:
考虑到我有如下Order
和OrderItem
类:
public class Order
{
public HashSet<OrderItem> _orderItems;
public Order()
{
_orderItems = new HashSet<OrderItem>();
}
public ImmutableHashSet<OrderItem> OrderItems
{
get => _orderItems.ToImmutableHashSet();
private set => _orderItems = value.ToHashSet();
}
public void AddOrderItem(OrderItem orderItem)
{
_orderItems.Add(orderItem);
}
public void RemoveOrderItem(OrderItem orderItem)
{
_orderItems.Add(orderItem);
}
}
public class OrderItem
{
public OrderItem(int orderId, string orderName)
{
OrderId = orderId;
OrderName = orderName;
}
public int OrderId { get; private set; }
public string OrderName { get; private set; }
}
Order
和OrderItem
类需要映射到下面的OrderDto
和类
public class OrderDto
{
public ICollection<OrderItem> OrderItems { get; set; }
}
public class OrderItemDto
{
public int OrderId { get; set; }
public string OrderName { get; set; }
}
下面的OrderProfile
类定义了自动映射器配置文件,以将Order
映射到OrderDto
,反之亦然。
public class OrderProfile : Profile
{
public OrderProfile()
{
CreateMap<Order, OrderDto>()
.ReverseMap();
CreateMap<OrderItem, OrderItemDto>()
.ReverseMap();
}
}
public class OrderItemDto
{
public int OrderId { get; set; }
public string OrderName { get; set; }
}
映射和反向映射Order
和OrderDto
类的代码:
private static void Map()
{
var mapper = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new OrderProfile());
}).CreateMapper();
var order = new Order();
order.AddOrderItem(new OrderItem(1, "Laptop"));
order.AddOrderItem(new OrderItem(2, "Keyboard"));
// This code maps correctly
var orderDto = mapper.Map<OrderDto>(order);
// This is where I get an exception
var orderMappedBack = mapper.Map<Order>(orderDto);
}
从Order
映射object
OrderDto
时,出现以下异常:
System.ArgumentException: System.Collections.Immutable.ImmutableHashSet`1[ReadOnlyCollectionDemo.OrderItem] needs to have a constructor with 0 args or only optional args. (Parameter 'type') at lambda_method(Closure , OrderDto , Order , ResolutionContext )
高度赞赏有助于解决此问题的任何指针。
更新
我以某种方式通过自定义Converter
使它起作用。但是我真的不知道它是如何工作的。我更新了我的映射器配置,如下所示:
var mapper = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new OrderProfile());
cfg.CreateMap(typeof(ICollection<>), typeof(ImmutableHashSet<>)).ConvertUsing(typeof(HashMapConverter<,>));
}).CreateMapper();
我的HashMapConverter
类:
public class HashMapConverter<TCollection, TImmutableHashSet>
: ITypeConverter<ICollection<TCollection>, ImmutableHashSet< TImmutableHashSet>>
{
public ImmutableHashSet< TImmutableHashSet> Convert(
ICollection<TCollection> source,
ImmutableHashSet< TImmutableHashSet> destination,
ResolutionContext context)
{
return ImmutableHashSet<TImmutableHashSet>.Empty;
}
}
[您可以看到我只是返回一个空的ImmutableHashSet
,但是令我惊讶的是OrderDto
现在已成功以正确的Order
OrderItems
数映射回Count
。由于我要返回一个空的Count
,因此我希望HashSet
为0。我怀疑它正在工作,因为OrderItem
和OrderItemDto
也通过AutoMapper
映射。
我想确认我的假设,并知道这是否是正确的方法。
在我的类似示例中,我没有得到0,所以最好使用]来完成转换功能。
public class HashMapConverter<TCollection, TImmutableHashSet> : ITypeConverter<ICollection<TCollection>, ImmutableHashSet<TImmutableHashSet>> { public ImmutableHashSet<TImmutableHashSet> Convert( ICollection<TCollection> source, ImmutableHashSet<TImmutableHashSet> destination, ResolutionContext context) { var hs =new HashSet<TCollection>(source); return ((IEnumerable<TImmutableHashSet>)hs).ToImmutableHashSet<TImmutableHashSet>(); //return ImmutableHashSet<TImmutableHashSet>.Empty; } }
而不是返回0;