C# Automapper:从多个接口绑定一个具体类
我正在尝试使用c和automapper映射一个类TrackingKeyStatic。 TrackingKeyStatic具有接口IBATCH处理从Trackingkey继承,Trackingkey具有接口ITrackingKey。 因此,根据定义,TrackingKeyStatic是IBatchProcessing和ITrackingKey Automapper仅使用一个接口IBatchProcessing即可正常工作 但无法使用接口ITrackingKey映射/检测 我制作了一把小提琴来演示 所以问题是如何将带有两个接口的源映射到croncrete类型 我尝试过这个配置,但它不起作用,这是我的问题C# Automapper:从多个接口绑定一个具体类,c#,automapper,C#,Automapper,我正在尝试使用c和automapper映射一个类TrackingKeyStatic。 TrackingKeyStatic具有接口IBATCH处理从Trackingkey继承,Trackingkey具有接口ITrackingKey。 因此,根据定义,TrackingKeyStatic是IBatchProcessing和ITrackingKey Automapper仅使用一个接口IBatchProcessing即可正常工作 但无法使用接口ITrackingKey映射/检测 我制作了一把小提琴来演示
cfg.CreateMap<ITrackingKey, MyEntitiesDbFirstModel>()
我已尝试更改的自动映射配置
cfg.CreateMap<TrackingKeyStatic<NotReleventClassForThisExample>, MyEntitiesDbFirstModel>()
正如TestWittrackingKeyStaticSource_方法所示,它的工作状态很好。但我不能为每个子类都创建映射
我尝试过使用.Include或.includealderived这样的方法,但不起作用,但我不太确定是否需要在这里使用它们?也许我做错了
下面是我为这个问题编写的单元测试
using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace StackOverflow
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestWithItrackingAsSource_NOTWORKING()
{
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<ITrackingKey, MyEntitiesDbFirstModel>()
.ForMember(d => d.TrackingKey, o => o.MapFrom(s => s.NewTrackingKey));
cfg.CreateMap<IBatchProcessing, MyEntitiesDbFirstModel>()
.ForMember(d => d.Skip, o => o.MapFrom(s => s.Skip))
.ForMember(d => d.Take, o => o.MapFrom(s => s.Take))
.ForMember(d => d.Total, o => o.MapFrom(s => s.Total));
});
var mapper = config.CreateMapper();
var source = new TrackingKeyStatic<NotReleventClassForThisExample>()
{
Skip = 10,
Take = 50,
Total = 123456,
NewTrackingKey = 987654
};
var actual = mapper.Map<MyEntitiesDbFirstModel>(source);
Assert.AreEqual(10, actual.Skip);//ok
Assert.AreEqual(50, actual.Take);//ok
Assert.AreEqual(123456, actual.Total);//ok
Assert.AreEqual(987654, actual.TrackingKey);//failed
}
[TestMethod]
public void TestWitTrackingKeyStaticAsSource_WORKING()
{
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<TrackingKeyStatic<NotReleventClassForThisExample>, MyEntitiesDbFirstModel>()
.ForMember(d => d.TrackingKey, o => o.MapFrom(s => s.NewTrackingKey));
cfg.CreateMap<IBatchProcessing, MyEntitiesDbFirstModel>()
.ForMember(d => d.Skip, o => o.MapFrom(s => s.Skip))
.ForMember(d => d.Take, o => o.MapFrom(s => s.Take))
.ForMember(d => d.Total, o => o.MapFrom(s => s.Total));
});
var mapper = config.CreateMapper();
var source = new TrackingKeyStatic<NotReleventClassForThisExample>()
{
Skip = 10,
Take = 50,
Total = 123456,
NewTrackingKey = 987654
};
var actual = mapper.Map<MyEntitiesDbFirstModel>(source);
Assert.AreEqual(10, actual.Skip);//ok
Assert.AreEqual(50, actual.Take);//ok
Assert.AreEqual(123456, actual.Total);//ok
Assert.AreEqual(987654, actual.TrackingKey);//work fine
}
}
public interface ITrackingKey
{
int NewTrackingKey { get; set; }
List<object> Records { get; set; }
}
public interface IBatchProcessing
{
int Skip { get; set; }
int Take { get; set; }
int Total { get; set; }
}
public class TrackingKey<T> : ITrackingKey
{
private List<object> _records;
public int NewTrackingKey { get; set; }
public List<T> Records //not relevent for question, it just for implementing interface
{
get { return _records?.Cast<T>()?.ToList(); }
set { _records = value?.Cast<object>()?.ToList(); }
}
List<object> ITrackingKey.Records //not relevent for question, it just for implementing interface
{
get { return _records; }
set { _records = value; }
}
}
public class TrackingKeyStatic<T> : TrackingKey<T>, IBatchProcessing
{
public int Skip { get; set; }
public int Take { get; set; }
public int Total { get; set; }
}
public class MyEntitiesDbFirstModel
{
public int Skip { get; set; }
public int Take { get; set; }
public int Total { get; set; }
public int TrackingKey { get; set; }
}
public class NotReleventClassForThisExample { public int MyProperty { get; set; }}
}
我能够使用一个小的hacky wrapper方法使其工作:
public static MyEntitiesDbFirstModel MapToMyDbModel<T>(TrackingKeyStatic<T> trackingKey, IMapper mapper)
{
var interimTypeObject = new TrackingKey<T>()
{
NewTrackingKey = trackingKey.NewTrackingKey
};
var actual = mapper.Map<MyEntitiesDbFirstModel>(trackingKey);
mapper.Map<ITrackingKey, MyEntitiesDbFirstModel>(interimTypeObject, actual);
return actual;
}
这是小提琴-
您可以进一步消除丑陋-当您使用TrackingKeyStatic时,AutoMapper似乎无法在此处选择正确的贴图,但在使用TrackingKey时没有问题。创建两个贴图,并使用同一对象两次。不太确定创建两个贴图是什么意思?这不是我正在做的吗?CreateMap[…];cfg.CreateMap[…]添加额外的行映射器不起作用。Mapsource,actual;?var-actual=mapper.Mapsource;var actual2=mapper.Mapsource,实际值;可悲的是,这并没有起到作用:你可以看到这里的修改是的,我之前在手机上。这是一个有趣的问题——实际上,automapper可能无法开箱即用。我已经给你添加了一个可能的答案,并且在这个问题上做得很好——准备得很好!在匹配地图时,您无法选择使用的源类型。始终使用源运行时类型。因此,如果不改变所涉及类型的结构,我看不到更干净的方法。