如何在 Automapper 中映射匿名对象

Posted

技术标签:

【中文标题】如何在 Automapper 中映射匿名对象【英文标题】:How to Map anonymous object in Auto Mapper 【发布时间】:2021-05-05 17:23:09 【问题描述】:

我试图在自动映射器中映射一个匿名对象,但不知道如何做到这一点。请在下面找到我的要求

我通过加入只有一个公共列 (Id) 的 2 个表来获取一些数据。我正在从此查询中获取匿名类型数据。

var query = (from _vdata in Table1
                  join entityFind in Table2 on _vdata.id equals entityFind.id
                  select new  entityFind.FamilyName, entityFind.LastLogin, entityFind.GivenName, 
                  entityFind.Email, entityFind.EmailVerified, entityFind.Uuid, _vdata.Role, 
                  _vdata.Payers, _vdata.Accounts, _vdata.ModifiedOn ).ToList();
        

我正在从上述查询中获取匿名数据。我在另一个变量中有更多数据列表,我需要将这些数据添加到此列表中,其中有限的列有 4-5 列。

在这种情况下如何在 AutoMapper 或任何其他技术中进行映射

谢谢

【问题讨论】:

不要。在需要的地方添加 FK 引用并使用 ProjectTo。不需要匿名类型。 【参考方案1】:

由于所有匿名类型都派生自 System.Object,我找到了一种解决方案(解决方法)来添加从对象到目标类型的映射

            //Allow to map anonymous types to concrete type
            cfg.CreateMap(typeof(object), typeof(ExternalCandle), 
                MemberList.None);

但请注意,对于大多数情况,这不是正确的解决方案 例如,如果你想映射 ORM 类型 - 使用这种方式:Queryable Extensions

我猜Jimmy bogard 不会推荐此解决方案,原因与从 AutoMappers 的 API 中删除 CreateMissingTypeMaps 的原因相同 - https://github.com/AutoMapper/AutoMapper/issues/3063

所以也许在 AutoMapper 的未来版本中,此代码将不起作用(我使用的是 AutoMapper 10.1.1,它对我有用)

【讨论】:

【参考方案2】:

您不能映射匿名类型。要实现上述功能,您可以创建如下模型:

public class ResultantData

    public string FamilyName  get; set; 
    public string LastLogin  get; set; 
    public string GivenName  get; set; 
    public string Email  get; set; 
    public string EmailVerified  get; set; 
    public string Uuid  get; set; 
    public string Role  get; set; 
    public string Payers  get; set; 
    public string Accounts  get; set; 
    public string ModifiedOn  get; set; 

然后你可以将上面的查询写成如下,并返回结果的 IQueryable:

var query = (from _vdata in Table1
                         join entityFind in Table2 on _vdata.id equals entityFind.id
                         select new ResultantData
                         
                             entityFind.FamilyName,
                             entityFind.LastLogin,
                             entityFind.GivenName,
                             entityFind.Email,
                             entityFind.EmailVerified,
                             entityFind.Uuid,
                             _vdata.Role,
                             _vdata.Payers,
                             _vdata.Accounts,
                             _vdata.ModifiedOn
                         );

当您想将此结果映射到实际模型时,您可以使用 Automapper 的ProjectTo 方法,如下所示:

var result = query.ProjectTo<ResultantDataModel>().ToList();

我使用下面的类作为结果模型:

public class ResultantDataModel

    public string FamilyName  get; set; 
    public string LastLogin  get; set; 
    public string GivenName  get; set; 
    public string Email  get; set; 
    public string EmailVerified  get; set; 
    public string Uuid  get; set; 
    public string Role  get; set; 
    public string Payers  get; set; 
    public string Accounts  get; set; 
    public string ModifiedOn  get; set; 

【讨论】:

那是手动映射。您可以简单地创建目的地:) 但是用户想要单独的 POCO Entity 和 ViewModel。 @LucianBargaoanu 这无关紧要。您要么手动映射,要么使用 AM。同时做这两件事没有什么意义。

以上是关于如何在 Automapper 中映射匿名对象的主要内容,如果未能解决你的问题,请参考以下文章

用于将匿名类型投影到视图模型上的 Automapper 查询

Linux中的mmap文件支持映射与匿名映射[关闭]

如何使用 AutoMapper 使用 EntityFramework 使用嵌套列表更新对象?

一文为你详细讲解对象映射库AutoMapper所支持场景

linux中匿名内存映射映射到哪个文件?

对 Java 的匿名内部类理解