【问题标题】:How can I use AutoMapper to map from DTOs to Entity Framework proxy classes?如何使用 AutoMapper 从 DTO 映射到实体框架代理类?
【发布时间】:2012-08-06 21:04:53
【问题描述】:

我有一个 REST 样式的 Web 应用程序,它首先使用 EF 代码。我正在使用 AutoMapper 将我的类映射到 DTO 类,以便通过网络传递,并(希望)返回。

当我从我的 POCO 类映射到 DTO 时,我实际上是从一个 EF 代理对象开始的,因为我正在处理的对象是对我的 DataContext 执行某种查询的结果。不过,这似乎工作正常。

当我将 DTO 类作为 POST 请求的一部分返回时,我可以使用 AutoMapper 将其映射到我的 POCO 类,this 也可以正常工作。

但是因为 AutoMapper 只是 new()-ing POCO 对象,而不是在 EntitySet 上使用 Create 方法,所以我现在有一个 POCO 类而不是相应的 EF 代理类.这让我更难将数据添加到我的数据库等中。

如何说服 AutoMapper 使用EntitySet.Create?或者有没有其他方法可以达到同样的效果?

【问题讨论】:

标签: entity-framework automapper poco dto


【解决方案1】:

Map.CreateMap 创建一个IMappingExpression 对象,该对象具有一个方法ConstructUsing,该方法接受一个函数,该函数可用作新对象的工厂方法。映射的属性用于设置值。 (顺便说一句,这可以被ConvertUsing 覆盖)。

详情请见Automapper - how to map to constructor parameters instead of property settersAutoMapper using the wrong constructorHow to use Automapper to construct object without default constructor

在你的情况下,这可能是这样的:

Mapper.CreateMap<TDto, TPoco>()
    .ConstructUsing((Func<TDto, TPoco>) (c => context.CreateObject<TPoco>()))

【讨论】:

    【解决方案2】:

    也许你可以这样做,

    首先创建所需的对象,然后使用该实例映射 DTO 对象,

    var poco=EntitySet.Create()
    
    Mapper.Map<DTOtype, POCOtype>(dto, poco); 
    

    【讨论】:

    • 是的,在单个对象的情况下,这看起来是一个不错的计划。但是,我的对象引用了我也想转换的其他对象。 (例如,一个带有多个 LineItem 对象的 Order 对象)。在这种情况下,我认为您建议的解决方案适用于 Order 对象,但不适用于 LineItems?
    【解决方案3】:

    假设您在 post 方法中接受 POCO 对象,而不是像 DTO 一样

    [HttpPost]
    public ActionResult Save(Student std)
    {
        //do the stuff
    }
    

    假设 Student 是 EF 代理类,但是当它使用 Modelbinder 绑定到表单值时,它会创建新对象,而不是与数据上下文关联的对象。所以第一件事是,如果您在帖子中接受 DTO,然后将它们转换为代理类,或者您首先接受代理类,这没有区别。 第二件事是,如果对象已经存在于数据库中并且您刚刚使用 automapper 创建了它,您可以使用 attach method 与 datacontext 关联。如果是新对象,则需要调用Add 方法将其保存到数据库中。

    【讨论】:

    • 我不确定我是否理解。我的 DTO 比我的 POCO 对象简单得多(更少的字段等),所以我不能在我的 ApiController 方法中简单地从 DTO 切换到 POCO——我确实需要“映射”它们。这就是我的问题的症结所在 - 即如何将它们映射到我的 POCO,但让这些 POCO 成为 EF 代理。
    • 好吧,我只想说,即使您设法在控制器中接收它们,它们也只是 POCO,而不是 EF 代理。您必须使用附加(如果实体已经在数据库中)或添加(如果实体是新的)等方法将它们附加到 EF 数据上下文中。
    • 我只是举个例子,不建议在控制器方法签名中使用db实体。
    • “即使您设法在控制器中接收它们,它们也只是 POCO 而不是 EF 代理”——这就是我的问题所在!我正在尝试直接或通过 POCO 从我的 DTO 创建 EF 代理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    • 2021-11-18
    • 2020-08-06
    相关资源
    最近更新 更多