实体框架 + AutoMapper(实体到DTO和DTO到实体)
我在使用 EF 和 AutoMapper 时遇到一些问题。 =/
例如:
我有 2 个相关实体(客户和订单) 它们是 DTO 类:
class CustomerDTO { public string CustomerID {get;set;} public string CustomerName {get;set;} public IList< OrderDTO > Orders {get;set;} }
订单DTO类 { 公共字符串订单ID {获取;设置;} 公共字符串 OrderDetails {get;set;} 公共 CustomerDTO 客户 {get;set;} }
//当将Entity映射到DTO时,代码可以工作 客户 cust = getCustomer(id); Mapper.CreateMap< 客户,CustomerDTO >(); Mapper.CreateMap< 订单,OrderDTO >(); CustomerDTO custDTO = Mapper.Map(cust);
//但是当我尝试从 DTO 映射回实体时,它失败并出现 AutoMapperMappingException。 映射器.Reset(); Mapper.CreateMap< CustomerDTO ,客户 >(); Mapper.CreateMap< OrderDTO ,订单 >(); 客户 customerModel = Mapper.Map< 客户DTO,客户>(custDTO); // 这里抛出异常
难道我做错了什么?
提前致谢 !
I've got some problems using EF with AutoMapper. =/
for example :
I've got 2 related entities ( Customers and Orders )
and they're DTO classes :
class CustomerDTO
{
public string CustomerID {get;set;}
public string CustomerName {get;set;}
public IList< OrderDTO > Orders {get;set;}
}
class OrderDTO
{
public string OrderID {get;set;}
public string OrderDetails {get;set;}
public CustomerDTO Customers {get;set;}
}
//when mapping Entity to DTO the code works
Customers cust = getCustomer(id);
Mapper.CreateMap< Customers, CustomerDTO >();
Mapper.CreateMap< Orders, OrderDTO >();
CustomerDTO custDTO = Mapper.Map(cust);
//but when i try to map back from DTO to Entity it fails with AutoMapperMappingException.
Mapper.Reset();
Mapper.CreateMap< CustomerDTO , Customers >();
Mapper.CreateMap< OrderDTO , Orders >();
Customers customerModel = Mapper.Map< CustomerDTO ,Customers >(custDTO); // exception is thrown here
Am I doing something wrong?
Thanks in Advance !
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
我遇到的问题与 EntityCollection 引用的更新有关。 从 DTO 映射到实体时,AutoMapper 会创建关系的新实例,这并不能让 EF 满意。
解决我问题的方法是将 AutoMapper 配置为使用 EntityCollection 属性的目标值。 在您的情况下:
这样 AM 将不会创建新的 EntityCollection 实例,并将使用原始 Customer 实体附带的实例。
我仍在寻找一种自动化的方法,但现在它解决了我的问题。
The problem I had was related to updates to EntityCollection references. AutoMapper creates a new instance of the relation when mapping from the DTO to the Entity, and that doesn't please the EF.
What solved my problem was configuring AutoMapper to use the destination value for my EntityCollection properties. In your case:
That way AM will not create a new EntityCollection instance, and will use that wich came with the original Customer entity.
I'm still working for a way to automate this, but for now it solves my problem.
尝试映射到现有对象:
并保留 Ignore() 的位置。
http://groups.google.com /group/automapper-users/browse_thread/thread/24a90f22323a27bc?fwc=1&pli=1
Try mapping to an existing object:
And keep the Ignore()'s in place.
http://groups.google.com/group/automapper-users/browse_thread/thread/24a90f22323a27bc?fwc=1&pli=1
您的问题是因为 Automapper 丢失了与记录关联的 EntityKey。 由于 EntityFramework 默认情况下不处理 POCO(普通旧 CLR 对象),
Jay Zimmerman 在此提供了一个很好的示例,说明如何处理此问题。 GD/4NIcj
另外,Jaroslaw Kowalski(我相信是 EF 团队的一部分)提供了在 EF 中使用 POCO 的示例,该示例可以很好地与 Automapper 一起使用(我还没有机会尝试): http://blogs.msdn .com/jkowalski/archive/2008/09/09/persistence-ignorance-poco-adapter-for-entity-framework-v1.aspx
Your problem is because Automapper loses the EntityKey associated with the record. As the EntityFramework does not by default handle POCO's (Plain Old CLR Object)
Jay Zimmerman has a good example here of how to handle this from is. gd /4NIcj
Also from Jaroslaw Kowalski (part of the EF team I believe ) has this example for using POCO's within EF, which may translate well to use with Automapper (I've not yet had a chance to try it) : http://blogs.msdn.com/jkowalski/archive/2008/09/09/persistence-ignorance-poco-adapter-for-entity-framework-v1.aspx
我不确定你的问题是什么,但是 - 当我想使用 LINQToEntities (切换到 NHibernate)时,
我成功地使用了自动映射器。
看一下代码:
它非常神秘,总是重新创建映射,但它有效。 我希望它能有所帮助。 :)
I'm not sure what your problem is, but - when i wanted to use LINQToEntities (switched to NHibernate),
i managed to use automapper with success.
Take a look at code:
It's quite cryptic, always recreates mappings, but it worked. I hope it helps somehow. :)
现在,对于新版本的 AutoMapper,推荐的方法是使用 Queryable-Extensions:
创建映射:
并将查询项目到 dto:
Now, with new version of AutoMapper, the recommended way is using Queryable-Extensions:
Create a mapping:
And project query to dto:
AutoMapper 在映射错误方面非常具有表现力。 仔细阅读异常消息。
另一件重要的事情是记住调用 Mapper.AssertConfigurationIsValid(); 创建映射后。 如果映射错误,它会给出错误,从而防止稍后在应用程序运行时出现异常。
AutoMapper is very expressive when it comes to mapping error. read the exception message carefully.
another important thing is to remember to call Mapper.AssertConfigurationIsValid(); after creating the mappings. it gives an error if the mapping is wrong, thus preventing an exception later in the application runtime.
您应该忽略某些实体属性的映射,如下所示:
如果您检查 Automapper 抛出的异常中的消息,您应该看到无法映射的实体属性并忽略它们,如上所述。
You should ignore mapping of some entity properties like so:
If you examine the message from the exception thrown by Automapper, you should see the entity properties that cannot be mapped and ignore them as above.
正如您可以在此处阅读,您需要执行以下操作
您可以使用 AutoMapper 更新实体。 方法如下:将 DTO 和实体对象传递给 AutoMapper 的 Map 方法。 这就是这段代码的作用:
还要注意映射问题,例如此处
这些技巧对我有用。
As you can read here you need to do the following
You can update entities with AutoMapper. Here's how: pass both the DTO and the entity object to AutoMapper's Map method. That's what this code does:
Also beware of mapping issues like the one described here
These tips worked for me.