继承类AutoMapper.AutoMapperMappingException

时间:2015-10-12 14:52:32

标签: automapper

我是automapper的新手,它是一款易于使用的好东西,但现在我遇到了问题。试图将我的派生类转换为基础,它给了我

  

AutoMapper.AutoMapperMappingException

     

缺少类型映射配置或不支持的映射。

     

映射类型:ClientEventDb - > EVENTID
        Database.ClientEventDb - > EVENTID

     

目标路径:ClientEvent

     

来源价值:

     

事件:登录

Automapper想要将ClientEventDb转换为EventId吗?我不明白为什么。 EventId是一个枚举...

请帮助我,我已经没有想法了。

以下是我运行的代码:

ClientEventDb[] edbl;
using (var context = new DbEntities())
{
    edbl=context.Events.Take(1000).ToArray();
}
Mapper.CreateMap<ClientEventDb, ClientEvent>();
Console.WriteLine("hello");
return edbl.Select(edb => Mapper.Map<ClientEvent>(edb)).ToArray();

这是我的课程

   [Table("events", Schema = "public")]
    public class ClientEventDb : ClientEvent
    {
        public ClientEventDb(string userName, EventId happening, object userObject = null)
            : base(userName, happening, userObject)
        {

        }
        public ClientEventDb()
        {

        }
    }

[ProtoContract]
[Table("events", Schema = "public")]
public class ClientEvent : ClientEventBase
{
    [ProtoMember(1)]
    [Column("username")]
    public string UserName { get; private set; }

    [ProtoMember(2)]
    [Column("time")]
    public DateTime DateTime { get; private set; }

    [ProtoMember(3)]
    [Key]
    [Column("id")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string Id { get; private set; }

    [ProtoMember(4)]
    [Column("data")]
    public byte[] UserObject { get; set; }

    public ClientEvent(string userName,EventId happening, object userObject=null) : base(happening)
    {
        UserName = userName;
        DateTime = DateTime.Now;
        //UserObject = null;
        if (userObject!=null) throw new NotImplementedException();
    }
    public ClientEvent()
    {

    }
    protected ClientEvent Clone()
    {
        return (ClientEvent)MemberwiseClone();
    }
}

[ProtoContract]
[ProtoInclude(10, typeof(ClientEvent))]
public class ClientEventBase
{

    [Column("eventid")]
    [ProtoMember(1)]
    public int EventIdValue { get; set; } //must be public because of entity framework

    [NotMapped]
    public EventId EventId
    {
        get { return (EventId) EventIdValue; }
        set { EventIdValue = (int) value; }
    }

    public ClientEventBase(EventId eventId)
    {
        EventId = eventId;
    }
    public ClientEventBase()
    {

    }
    public override string ToString()
    {
        return String.Format("Event:{0}",EventId);
    }
}

public enum EventId
{
    Login = 1,
    Logout,
    ExitApplication,
}

更新

错误修正:ClientEvent [Key]属性已移至id属性

解决方案是这个(thx to stuartd):

ClientEventDb[] edbl;
using (var context = new DbEntities())
{
    edbl=context.Events.ToArray();
}
Mapper.CreateMap<ClientEventDb, ClientEvent>().ConstructUsing((ClientEventDb src) => new ClientEvent());
return edbl.Select(Mapper.Map<ClientEvent>).ToArray();

2 个答案:

答案 0 :(得分:4)

AutoMapper被混淆为在不同类中的类似属性之间进行映射,您使用它的方法不正确 - 您只需要从派生类转到不需要AutoMapper的基类。你可以用它来做你需要的......

ClientEventDb[] edbl;
using (var context = new DbEntities())
{
    edbl=context.Events.Take(1000).ToArray();
}

return edbl.Cast<ClientEvent>().ToList();

我会看到为什么你甚至觉得你需要一个派生的ClientEventDb - 理解我们这里没有完整的图片,但它似乎除了基类已经做了什么之外什么也没做。

答案 1 :(得分:2)

问题是ClientEvent有两个构造函数但你没有告诉AutoMapper使用哪个。

如果您希望它使用带有参数的构造函数,请将映射代码更改为此代码,它将起作用:

Mapper.CreateMap<ClientEventDb, ClientEvent>()
      .ConstructUsing(src => new ClientEvent(src.UserName, src.EventId));

或者使AutoMapper使用默认构造函数:

Mapper.CreateMap<ClientEventDb, ClientEvent>()
      .ConstructUsing((ClientEventDb src) => new ClientEvent());