Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Automapper:从多个接口绑定一个具体类_C#_Automapper - Fatal编程技术网

C# Automapper:从多个接口绑定一个具体类

C# Automapper:从多个接口绑定一个具体类,c#,automapper,C#,Automapper,我正在尝试使用c和automapper映射一个类TrackingKeyStatic。 TrackingKeyStatic具有接口IBATCH处理从Trackingkey继承,Trackingkey具有接口ITrackingKey。 因此,根据定义,TrackingKeyStatic是IBatchProcessing和ITrackingKey Automapper仅使用一个接口IBatchProcessing即可正常工作 但无法使用接口ITrackingKey映射/检测 我制作了一把小提琴来演示

我正在尝试使用c和automapper映射一个类TrackingKeyStatic。 TrackingKeyStatic具有接口IBATCH处理从Trackingkey继承,Trackingkey具有接口ITrackingKey。 因此,根据定义,TrackingKeyStatic是IBatchProcessing和ITrackingKey

Automapper仅使用一个接口IBatchProcessing即可正常工作 但无法使用接口ITrackingKey映射/检测

我制作了一把小提琴来演示

所以问题是如何将带有两个接口的源映射到croncrete类型

我尝试过这个配置,但它不起作用,这是我的问题

 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可能无法开箱即用。我已经给你添加了一个可能的答案,并且在这个问题上做得很好——准备得很好!在匹配地图时,您无法选择使用的源类型。始终使用源运行时类型。因此,如果不改变所涉及类型的结构,我看不到更干净的方法。