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