我该如何使用AutoMapper将DTO映射到Entity Framework代理类?

3
我有一个使用EF Code First的REST风格的Web应用程序。我使用AutoMapper将我的类映射到DTO类以便通过网络传输和(希望)返回。
当我从POCO类映射到DTO时,实际上是从EF代理对象开始的,因为我所处理的对象是针对我的DataContext执行某种查询的结果。这似乎很正常。
当我在POST请求的一部分中收到DTO类时,我可以使用AutoMapper将其映射到我的POCO类,而且这也很正常。
然而,因为AutoMapper只是新建POCO对象而不是使用EntitySet.Create方法创建它们,所以现在我只有一个POCO类而没有对应的EF代理类。这使我更难将数据添加到数据库中等操作。
我该如何说服AutoMapper使用EntitySet.Create?或者是否有其他方法可以达到相同的效果?

据我所知,AutoMapper不能像某些IoC容器那样使用工厂方法进行扩展。这是一个非常合理的补充,但也许你需要自己做出贡献! - Gert Arnold
我不知道得够深入:https://dev59.com/iHE95IYBdhLWcg3wmvGh 和 https://dev59.com/LGgu5IYBdhLWcg3wso-j。 - Gert Arnold
@GertArnold:太好了!你应该把它作为答案添加,我会接受它。 - Gary McGill
3个回答

3

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>()))

1

也许你可以这样做:

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

var poco=EntitySet.Create()

Mapper.Map<DTOtype, POCOtype>(dto, poco); 

是的,在单个对象的情况下,那看起来是一个不错的计划。然而,我的对象有对其他对象的引用,我也希望它们被转换。(例如,一个包含多个LineItem对象的Order对象)。在这种情况下,我认为您提出的解决方案适用于Order对象,但不适用于LineItems? - Gary McGill

0
假设您在post方法中接受POCO对象而不是DTO。
[HttpPost]
public ActionResult Save(Student std)
{
    //do the stuff
}

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


我不确定我理解了。我的DTO比我的POCO对象简单得多(字段更少等),所以我不能在我的ApiController方法中简单地从DTO切换到POCO - 我确实需要“映射”它们。这就是我的问题的关键 - 即如何将它们映射到我的POCO,但让这些POCO成为EF代理。 - Gary McGill
我要说的是,即使你在控制器中成功接收它们,它们只会是POCO而不是EF代理。你需要使用EF数据上下文的方法(如attach(如果实体已经在数据库中)或add(如果实体是新的))将它们附加到EF数据上下文中。 - Muhammad Adeel Zahid
我只是举了一个例子,不建议在控制器方法签名中使用数据库实体。 - Muhammad Adeel Zahid
即使您在控制器中成功接收它们,它们也只是POCO而不是EF代理 - 这就是我的问题所在!我正在尝试从我的DTO直接或通过POCO创建EF代理。 - Gary McGill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接