【问题标题】:NHibernate's SaveOrUpdate throws NonUniqueObjectException when child collections mapped via automapper当子集合通过自动映射器映射时,NHibernate 的 SaveOrUpdate 会抛出 NonUniqueObjectException
【发布时间】:2014-12-19 05:11:52
【问题描述】:

我有一个 Employee 类,其中包含 Addresses 作为属性,如下所示,以及相应的 DTO 的 EmployeeDTO 和 AddressDTO

public class EmployeeDTO {
    public string Name { get; set; }
    public IList<AddressDTO> Addresses { get; set; }
}

public class Employee {
    public virtual string Name { get; set; }
    public virtual IList<Address> Addresses { get; set; }
}

我的 AutoMapper 映射仅此而已,但为了方便起见,我只显示直接映射。

Mapper.CreateMap<EmployeeDTO, Employee>();
Mapper.CreateMap<Employee, EmployeeDTO>();

Mapper.CreateMap<AddressDTO, Address>();
Mapper.CreateMap<Address, AddressDTO>();

在我的数据层中,我通过其名称获取一个 Employee,然后将其转换为 EmployeeDTO 并将其传输到 UI。 在 UI 中,我更改了地址或将新地址添加到 EmployeeDTO 的地址,然后将其传输回服务器以保留。 在存储库中,我从数据库中获取现有员工,然后使用 AutoMapper 更新对象。我使用 AutoMapper 的 Map 重载来返回相同的实体

TDestination Map<TSource, TDestination>(TSource source, TDestination destination);
var empObj = Mapper.Map<EmployeeDTO, Employee>(updatedDTO, empInDb);

我使用会话的 SaveOrUpdate 来持久化

_session.SaveOrUpdate(empObj);

提交时会抛出异常

“具有相同标识符值的不同对象已与会话相关联:4,实体:地址”

如果我使用 _session.Merge 它可以正常工作,但以前当我使用手动映射而不是 AutoMapper 时,它可以正常使用 'session.SaveOrUpdate'。

  1. 那么当我使用 AutoMapper 进行映射时出了什么问题。我猜想在 automapper 内部,当它看到 List 和 List 之间的映射时,它只使用法线贴图。我们可以指定某个地方,以便 AutoMapper 使用 Map 的重载,以便它返回相同的实体。
  2. 我发现 SaveOrUpdate 和 Merge 之间的速度差异很小。无论如何要加快速度。

【问题讨论】:

标签: c# wcf nhibernate automapper soa


【解决方案1】:

不支持使用 AutoMapper 进行复杂的反向映射。映射集合很难。您必须合并两个集合、删除不存在的内容、添加新内容等。您还必须定义一些机制来将现有源 DTO 与目标模型匹配。

如果您手动编写反向代码,您会看到遇到了什么问题。不要反转映射复杂对象,它不受支持,而且可能永远不会。

【讨论】:

  • 为了便于理解,我简化了上面的代码。在我的实际代码中,我指定了如何将每个属性从 DTO 映射到 BO 以及从 BO 映射到 DTO(分别)。 AutoMapper 完美地映射对象。我只收到 NHibernate 部分的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-13
  • 1970-01-01
  • 2011-02-10
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多