【问题标题】:What are the different approaches to Object-Object mapping in .NET?.NET 中对象-对象映射的不同方法是什么?
【发布时间】:2016-12-26 17:02:08
【问题描述】:

我需要在对象之间进行一些映射(例如,PersonModel 到 PersonViewModel),并且正在研究不同的方法来做到这一点。具体来说,我正在使用实体框架并尝试将生成的模型映射到视图模型。

但是,我还没有找到一篇文章或资源来汇编如何执行此操作的列表。到目前为止,我遇到了以下情况:

  • 隐式转换(我认为这是最基本的方法?因为您手动将属性从一个对象映射到另一个对象,它简单但乏味)
  • 扩展方法(尚未使用此功能)
  • 反射(我做了一些修改,但只管理了非常基本的映射)
  • Automapper(非常流行,但我无法让它与 EF 一起正常工作)
  • Value Injecter(尚未使用此功能)
  • Emit Mapper(尚未使用此功能,但可能无法使其与 EF 一起使用?)

能否请您指出并详细说明那里可用的方法,以及每种方法的优缺点?例如,我看到一些提到 Automapper 比手动映射慢?或者可能,指出一篇解决这个问题的文章?

编辑:因为有些人可能会问我对 AutoMapper 有什么问题,请参阅:Automapper: How to map IList to EntityCollection

【问题讨论】:

  • 您询问的是整篇文章甚至一本书的章节。 SO 是一个问答网站。 Automapper 使用 EF 没有问题,主要是因为 EF 返回的对象是普通对象。如果您使用 EF 特定的类,例如 EntityCollection,那么您做错了。查看所有教程,您会发现他们使用的是最基本的ICollection<T>
  • 你也可以Explicit Casting

标签: c# .net orm object-object-mapping


【解决方案1】:

好吧,我可以为您提供一种方法,让您自己进行映射,操作非常简单,并且可以在大量数据上快速执行。我会告诉你我会做什么,然后尝试详细说明我为什么做我所做的事情。如下:

public class PersonViewModel
{
    public static Expression<Func<Person, PersonViewModel>> FromPerson
    {
        get
        {
            return p => new PersonViewModel
            {
                Name = p.FirstName,
                SurName = p.LastName
            };
        }
    }

    public string Name { get; set; }
    public string SurName { get; set; }
    public static PersonViewModel CreateViewModel(Person original)
    {
        var func = FromPerson.Compile();
        var vm = func(original);

        return vm;
    }
}

现在您会注意到我有两种方法可以将 Person EF 模型转换为 ViewModel。这是因为第一个使用 Expression>,用于在 Select() 语句中转换大量对象。简单用法:

return people.Select(PersonViewModel.FromPerson);

在这种情况下,我们可能已经从数据库中检索了一组 Person 对象,并且需要将它们显示在列表或其他东西中,但使用 ViewModel。通过这种方式,操作是批量执行的,并且比通过其他方法简单地创建所有对象要快得多。现在,静态 CreateViewModel 方法可用于在需要的地方映射单个对象。例如,如果您从数据库中获取了单个用户的数据并需要显示它,但使用您的 ViewModel。在这种情况下,最好使用静态方法,而不是主要用于批量转换的表达式。

这就是我可以提供的,除了想知道使用 AutoMapper 有什么问题之外,因为它非常简单,而且您还没有真正详细说明与 EF 一起使用它会出现什么问题。希望这至少对您的问题有所帮助:)

【讨论】:

  • 我建议CreateViewModel 使用FromPerson 来减少代码重复。几乎任何现实生活中的映射都会有更多的属性,因此应用 DRY(不要重复自己)原则是有意义的。
  • 啊,你说得对,我其实忘了,因为我是在飞行中写的,感谢您的更正,会修复它。
【解决方案2】:

好吧,如果你事先知道对象的类型,那么接受的答案就很好。

如果不是,我会选择 AutoMapper 或 PropMapper。

如果您想推出自己的东西,最“最新”的方法是使用已编译的表达式树。你枚举类型的属性,然后为每个属性构建一个赋值表达式块,然后“编译”这个块:

var e = Expression.Assign(Expression.Property(srcObj, prop1), Expression.Property(destObj, prop2)));

这是关于此问题的分步博客文章:https://dev.to/alexjitbit/yet-another---lightning-fast---object-mapper-for-net-2bj2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-19
    • 2013-08-01
    • 2012-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多