使用NHibernate代理的Automapper + DTO

时间:2014-01-27 17:16:43

标签: c# nhibernate automapper

我在使用AutoMapper将对象从Nhibernate查询转换为我的DTO时遇到以下问题

假设我有4节课。

    class A
{
    //some fields of built-in type
}
abstract class B //Some class derived this one, but this is not important here
{
    //some fields of built-in type
    public A refA { get; set; }
}
class C
{
    //some fields of built-in type
    public B refB { get; set; }
}
class D
{
    //some fields of built-in type
    public B refC { get; set; }
}

我使用AutoMapper将其转换为我的DTO,为简单起见,我们假设DTO是这些类的精确副本。 我希望通过线路发送,所以在序列化之前,我要求AutoMapper将其转换为与D-Class相对应的DTO。

当我调用

时,如果我创建这些Object并配置my-self字段
Mapper.Map<T1,T2>(T1 source)

这很有效。所以我的配置AutoMap正在运行。更多它也与

合作
Mapper.Map<IList<T1>,List<T2>

很好。

现在我创建了这些对象,我将它们放在数据库中并使用Nhibernate向我的SQL DB调用请求以检索IList(D类列表)。

如果我现在尝试在DTO中转换它,它就不再起作用了。 我在AutoMap中跟踪代码,它正确地映射了class D中的所有内置类型字段,然后它来到了refC,并在这里崩溃了。

我知道延迟加载以及Nhibernate只是将我的ref的代理命名为C类,但我不知道如何解决这个问题。 只是你知道NHibernateUtil.IsInitialized(refC) is true

非常感谢

2 个答案:

答案 0 :(得分:2)

在将实体传递给automapper之前,您必须取消其实例。这基本上与您运行Json序列化的问题相同。

您可以使用

Session.GetSessionImplementation().PersistenceContext.Unproxy();

解开某些东西。

或者您禁用延迟加载。

或者您不使用automapper而是使用标准转换...例如

.Query().Select(p => new SomeDto(){ PropA = p.PropA, ...});

答案 1 :(得分:0)

您还可以使用其他标准方式:

resultSet = session.CreateCriteria(typeof(DataObject))
    .Add(query criteria, etc.)
    .SetResultTransformer(Transformers.AliasToBean<DTOObject>())
    .List<IDTOObject>()

基本上你不必迭代所有的道具。在DTO和数据对象之间建立相同的所有类别道具就足够了。