NHibernate和ASP.NET web api服务中的LazyLoad

NHibernate和ASP.NET web api服务中的LazyLoad,nhibernate,asp.net-web-api,fluent-nhibernate,lazy-loading,Nhibernate,Asp.net Web Api,Fluent Nhibernate,Lazy Loading,我有以下数据模型 public class Profile : Entity { public virtual string Name { get; set; } public virtual int Sequence { get; set; } public virtual string Description { get; set; } public virtual IList<MapService> MapServices { get; set;

我有以下数据模型

public class Profile : Entity
{
    public virtual string Name { get; set; }
    public virtual int Sequence { get; set; }
    public virtual string Description { get; set; }
    public virtual IList<MapService> MapServices { get; set; }
}

public class MapService : Entity
{
    public virtual string Name { get; set; }
    public virtual string Url { get; set; }
    public virtual int MaximumResolution { get; set; }
}
我在API控制器中使用NHibernate进行数据访问

Web API控制器如下所示

public class ProfilesController : ApiController
{
    public ProfilesController()
    {
    }

    public IEnumerator<Profile> GetAllProfiles()
    {
        using (Session = .. create nhibernate session )
        {
            return Session.Query<Profile>().GetEnumerator();
        }
    }
}
我得到这个错误

消息:发生错误。。异常消息:“ObjectContent`1”类型未能序列化内容类型“application/json”的响应正文

消息:发生错误。异常消息:初始化[Domain.Profile2]-未能延迟初始化角色集合:Domain.Profile.MapServices,未关闭任何会话或会话,异常类型:NHibernate.LazyInitializationException,StackTrace:

nhibernate似乎正在返回没有mapservices的概要文件列表,并关闭会话

但不知何故,web api服务试图在序列化期间访问映射服务列表


如何告诉web api服务忽略地图服务列表?

这里的简单方法是引入DTO对象:

public class ProfileDto
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Sequence { get; set; } // or Guid...
    public virtual string Description { get; set; }
    ... // if more needed
}
然后调整API控制器方法

public IEnumerable<ProfileDto> GetAllProfiles()
{
    using (var session = ...)
    {
        return session.Query<Profile>()
            .Select(entity => new ProfileDto
            {
                Id = entity.ID,
                Name = entity.Name,
                Sequence = entity.Sequence,
                Description = entity.Description,
            })
            .ToList();
    }
}

这里最重要的是call.ToList,它将确保来自DB服务器的所有加载都是在会话生存期using子句中完成的。Automapper可能是下一步,使其更容易使用更少的代码…

这里的简单方法是引入DTO对象:

public class ProfileDto
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Sequence { get; set; } // or Guid...
    public virtual string Description { get; set; }
    ... // if more needed
}
然后调整API控制器方法

public IEnumerable<ProfileDto> GetAllProfiles()
{
    using (var session = ...)
    {
        return session.Query<Profile>()
            .Select(entity => new ProfileDto
            {
                Id = entity.ID,
                Name = entity.Name,
                Sequence = entity.Sequence,
                Description = entity.Description,
            })
            .ToList();
    }
}
这里最重要的是call.ToList,它将确保来自DB服务器的所有加载都是在会话生存期using子句中完成的。Automapper可能是下一步,让它更简单,更少的代码

public IEnumerable<ProfileDto> GetAllProfiles()
{
    using (var session = ...)
    {
        return session.Query<Profile>()
            .Select(entity => new ProfileDto
            {
                Id = entity.ID,
                Name = entity.Name,
                Sequence = entity.Sequence,
                Description = entity.Description,
            })
            .ToList();
    }
}