【问题标题】:AutoMapper 4 mapping ErrorAutoMapper 4 映射错误
【发布时间】:2015-08-14 17:16:51
【问题描述】:

我有两节课。一个是名为“ImportedContact”的类,它映射到 csv 文件中的记录。对于文件中的每一行,都有一个此类的实例。我们使用 LINQtoCSV 库将值检索到此类中。第二个是与 Telerik 的 DataAccess ORM 库一起使用的名为“Contact”的类。所以我们的过程是使用 LINQtoCSV 读取 csv 文件,填充 ImportedContact 类实例,并将它们每个映射到一个 Contact 类实例中,我们将它们添加到数据库上下文并更新我们的数据库。当我们在这些类之间进行映射时,我得到一个对我来说没有意义的异常。

这是 ImportedContact 类:

using System;
using System.Linq;
using LINQtoCSV;

namespace SharePointDirectory.Jobs
{
    public class ImportedContact
    {
        [CsvColumn(Name = "Location Name", FieldIndex = 4)]
        public string BranchId
        {
            get;
            set;
        }

        [CsvColumn(Name = "Work Wireless", FieldIndex = 7)]
        public string CellNumber
        {
            get;
            set;
        }

        [CsvColumn(Name = "Home Department Name", FieldIndex = 3)]
        public string Dept
        {
            get;
            set;
        }

        [CsvColumn(Name = "Extension", FieldIndex = 9)]
        public string Ext
        {
            get;
            set;
        }

        [CsvColumn(Name = "First Name", FieldIndex = 2)]
        public string FirstName
        {
            get;
            set;
        }

        [CsvColumn(Name = "Last Name", FieldIndex = 1)]
        public string LastName
        {
            get;
            set;
        }

        [CsvColumn(Name = "Shift -- Value", FieldIndex = 5)]
        public string Shift
        {
            get;
            set;
        }

        [CsvColumn(Name = "Job Title", FieldIndex = 8)]
        public string Title
        {
            get;
            set;
        }

        [CsvColumn(Name = "Work Phone", FieldIndex = 6)]
        public string WorkNumber
        {
            get;
            set;
        }
    }
}

这是联系人类:

using System;
using System.Linq;
using System.Runtime.Serialization;

namespace SharePointDirectory.Data  
{
    [Serializable]
    public class Contact : ISerializable
    {
        public Contact()
        {
        }

        protected Contact(SerializationInfo info, StreamingContext context)
        {
            this.Id = info.GetInt64("Id");
            this.EmployeeId = (int?)info.GetValue("EmployeeId", typeof(int?));
            this.FirstName = info.GetString("FirstName");
            this.LastName = info.GetString("LastName");
            this.Title = info.GetString("Title");
            this.Ext = info.GetString("Ext");
            this.Dept = info.GetString("Dept");
            this.DeptId = info.GetString("DeptId");
            this.CellNumber = info.GetString("CellNumber");
            this.PhotoPath = info.GetString("PhotoPath");
            this.Active = info.GetBoolean("Active");
            this.Office = info.GetBoolean("Office");
            this.Shift = info.GetString("Shift");
            this.BranchId = info.GetString("BranchId");
            this.WorkNumber = info.GetString("WorkNumber");
        }

        public bool Active
        {
            get;
            set;
        }

        public string BranchId
        {
            get;
            set;
        }

        public string CellNumber
        {
            get;
            set;
        }

        public string Dept
        {
            get;
            set;
        }

        public string DeptId
        {
            get;
            set;
        }

        public int? EmployeeId
        {
            get;
            set;
        }

        public string Ext
        {
            get;
            set;
        }

        public string FirstName
        {
            get;
            set;
        }

        public long Id
        {
            get;
            set;
        }

        public string LastName
        {
            get;
            set;
        }

        public bool Office
        {
            get;
            set;
        }

        public string PhotoPath
        {
            get;
            set;
        }

        public string Shift
        {
            get;
            set;
        }

        public string Title
        {
            get;
            set;
        }

        public string WorkNumber
        {
            get;
            set;
        }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Id", this.Id, typeof(long));
            info.AddValue("EmployeeId", this.EmployeeId, typeof(int?));
            info.AddValue("FirstName", this.FirstName, typeof(string));
            info.AddValue("LastName", this.LastName, typeof(string));
            info.AddValue("Title", this.Title, typeof(string));
            info.AddValue("Ext", this.Ext, typeof(string));
            info.AddValue("Dept", this.Dept, typeof(string));
            info.AddValue("DeptId", this.DeptId, typeof(string));
            info.AddValue("CellNumber", this.CellNumber, typeof(string));
            info.AddValue("PhotoPath", this.PhotoPath, typeof(string));
            info.AddValue("Active", this.Active, typeof(bool));
            info.AddValue("Office", this.Office, typeof(bool));
            info.AddValue("Shift", this.Shift, typeof(string));
            info.AddValue("BranchId", this.BranchId, typeof(string));
            info.AddValue("WorkNumber", this.WorkNumber, typeof(string));
        }
    }
}

以下是我们设置映射的方式:

Mapper.Initialize(configuration => configuration.CreateMap<ImportedContact, Contact>());

这是我们在运行时执行实际地图的方式:

var contact = Mapper.Map<Contact>(importedContact);

当我们执行映射时,这是我们看到的异常消息:

{
    "Missing type map configuration or unsupported mapping.

    Mapping types:
    ImportedContact -> SerializationInfo
    SharePointDirectory.Jobs.ImportedContact -> System.Runtime.Serialization.SerializationInfo

    Destination path:
    Contact

    Source value:
    SharePointDirectory.Jobs.ImportedContact"
}   

System.Exception {AutoMapper.AutoMapperMappingException}

我不明白它为什么要尝试对那里列出的这两种类型执行映射。 SerializationInfo 是其中一个构造函数的构造函数参数,但我觉得它也应该关注一个无参数构造函数,而不是相反。同样的代码在 AutoMapper 3.3 版中似乎也能正常工作。

我一直在查看 AutoMapper 文档,看看是否能找到任何东西。到目前为止,最接近的是提到这两件事。

https://github.com/AutoMapper/AutoMapper/wiki/Construction

https://github.com/AutoMapper/AutoMapper/wiki/Configuration

关于配置前缀的具体说明:

By default AutoMapper recognizes the prefix "Get"

【问题讨论】:

    标签: c# serialization orm automapper poco


    【解决方案1】:

    我遇到了类似的问题,AutoMapper 决定使用带参数的构造函数而不是默认构造函数。

    我的解决方法是自己实例化目标对象并让AutoMapper 填写属性:

    var contact = new Contact();
    Mapper.Map(importedContact, contact);
    

    【讨论】:

    • 我的示例显示了导致问题的两种特定类型。但实际上代码是用泛型 编写的。所以我们一直依赖 Automapper 执行 Td 类型的对象实例化。我们将不得不重构代码以执行我们自己的 Activator.CreateInstance 来调用它。我有点希望可以在映射配置中表达一些东西,而不是只能在 API 中调用特定的 Map 方法。
    • 我明白了。我认为在较新版本的 AutoMapper 中行为发生了变化,因为通过 NuGet 升级后出现错误。不知道有没有配置,不好意思。我会保留我的答案,因为它可能对其他人有用。
    【解决方案2】:

    我不确定自动映射器的 never 版本,但我认为,您仍然需要指定目标映射类,否则它不知道映射到哪里。

    var contact = Mapper.Map<ImportedContact, Contact>(importedContact);
    

    【讨论】:

    • Automapper 不需要声明这两种类型。它可以确定通过参数隐含的源类型。目标类型通过泛型声明给出。 Automapper 在版本 3 中支持此语法/api。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-02
    相关资源
    最近更新 更多