Copying NHibernate POCO to DTO without triggering lazy load or eager load

空扰寡人 提交于 2019-11-29 14:59:13

for ValueInjecter solution I recommend using SmartConventionInjection (you need to copy the code from the linked page into your solution)

and after specify a convention that won't touch the proxy properties

here's a start:

public class MapPoco: SmartConventionInjection
{
     protected override bool Match(SmartConventionInfo c)
     {
         return c.SourceProp.Name == c.TargetProp.Name;
     }
}

I solve this by selecting DTO's as projections using Linq or whatever query language the O/R Mapper may have.

e.g.

return from c in customers 
       select new CustomerDTO 
       {
          Name = c.Name , 
          Orders = c.Orders.Select (o => new OrderDTO {...} ) 
       };

This way, you don't need to resort to reflection magic or any other fancy stuff. And the query fetches exactly what you need in one go, thus, this is usually much more efficient than fetching entities and then transforming them to DTO's in mem. (it can be less efficient in some cases incase the resulting SQL query contains extra joins for whatever reason..)

I'm using the following ValueResolver with AutoMapper:

/// <summary>
/// ValueResolver that will set NHibernate proxy objects to null, instead of triggering a lazy load of the object
/// </summary>
public class IgnoreNHibernateProxyValueResolver : IValueResolver
{
    public ResolutionResult Resolve(ResolutionResult source)
    {
        var prop = source.Type.GetProperty(source.Context.MemberName).GetValue(source.Value, null);
        var proxy = prop as INHibernateProxy;
        if (proxy != null && proxy.HibernateLazyInitializer.IsUninitialized)
        {
            return source.Ignore();
        }

        return source.New(prop);
    }
}

Take a look on Projections in Introduction to QueryOver in NH 3.0

CatSummary summaryDto = null;
IList<CatSummary> catReport =
    session.QueryOver<Cat>()
        .SelectList(list => list
            .SelectGroup(c => c.Name).WithAlias(() => summaryDto.Name)
            .SelectAvg(c => c.Age).WithAlias(() => summaryDto.AverageAge))
        .TransformUsing(Transformers.AliasToBean<CatSummary>())
        .List<CatSummary>();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!