简体   繁体   中英

Automapper + DTO with an NHibernate Proxy

I'm having difficulty using AutoMapper to convert Object from Nhibernate queries into my DTO in the following conf

Let's say I have 4 class.

    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; }
}

I use AutoMapper to convert it to my DTO, lets assume for simplicity here that the DTO is an exact copy of these class. I want to send this through the wire, so before serializing, I ask AutoMapper to convert it in the DTO corresponding to the D-Class.

If I make these Object and configure the field my-self, when I call

Mapper.Map<T1,T2>(T1 source)

This is working. So my configuration AutoMap is working. More its also working with

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

Very well.

Now I make these object, I put them in a Database and call a request to my SQL DB with Nhibernate to retrieve an IList (List of class D).

If I now try to convert it in DTO, it doesnt work anymore. I trace the code in AutoMap, it maps correctly all the built-in type field in class D and then it comes to the refC and here it crash somewhere.

I know about lazy-loading and the fact that Nhibernate just gimme a proxy of my ref to class C but I dont see how to solve this. Just so you know the NHibernateUtil.IsInitialized(refC) is true

Many Thanks

You will have to unproxy your entities before passing it to automapper. This is basically the same issue as if you would run a Json serialization.

You can use

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

to unproxy something.

Or you disable lazy loading.

Or you do not use automapper and instead use standard transformations... eg

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

You can also use another standard way:

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

Basically you don't have to iterate all of the props. It is enough to be the same all class props between your DTO and data object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM