jam*_*vey 20 nhibernate asp.net-mvc fluent-nhibernate
我有以下看似简单的场景,但是我对NHibernate还是一个新手.
尝试在Controller上为"编辑"操作加载以下模型时:
控制器的编辑操作:
public ActionResult Edit(Guid id)
{
return View(_repository.GetById(id));
}
Run Code Online (Sandbox Code Playgroud)
库:
public SomeModel GetById(Guid id)
{
using (ISession session = NHibernateSessionManager.Instance.GetSession())
return session.Get<SomeModel >(id);
}
Run Code Online (Sandbox Code Playgroud)
模型:
public class SomeModel
{
public virtual string Content { get; set; }
public virtual IList<SomeOtherModel> SomeOtherModel { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
- 懒得初始化角色集合:SomeOtherModel,没有关闭会话或会话
我在这里错过了什么?
Ste*_*ger 21
问题是您在模型GetById方法中创建并关闭会话.(using语句关闭会话)会话必须在整个业务事务期间可用.
有几种方法可以实现这一目标.您可以配置NHibernate以使用会话工厂GetCurrentSession方法.请参阅nhibernate.info或Code Project上的这篇文章.
public SomeModel GetById(Guid id)
{
// no using keyword here, take the session from the manager which
// manages it as configured
ISession session = NHibernateSessionManager.Instance.GetSession();
return session.Get<SomeModel >(id);
}
Run Code Online (Sandbox Code Playgroud)
我不用这个.我写了自己的交易服务,允许以下内容:
using (TransactionService.CreateTransactionScope())
{
// same session is used by any repository
var entity = xyRepository.Get(id);
// session still there and allows lazy loading
entity.Roles.Add(new Role());
// all changes made in memory a flushed to the db
TransactionService.Commit();
}
Run Code Online (Sandbox Code Playgroud)
无论如何实现它,会话和事务应该与业务事务(或系统功能)一样长.除非你不能依赖事务隔离,也不能回滚整个事情.
Dar*_*rov 10
SomeOtherModel如果您打算在关闭会话之前使用它,则需要急切地加载集合:
using (ISession session = NHibernateSessionManager.Instance.GetSession())
{
return session
.CreateCriteria<SomeModel>()
.CreateCriteria("SomeOtherModel", JoinType.LeftOuterJoin)
.Add(Restrictions.Eq(Projections.Id(), id))
.UniqueResult<SomeModel>();
}
Run Code Online (Sandbox Code Playgroud)
默认情况下,FluentNHibernate 使用延迟加载进行集合映射.另一个选项是在映射中修改此默认行为:
HasMany(x => x.SomeOtherModel)
.KeyColumns.Add("key_id").AsBag().Not.LazyLoad();
Run Code Online (Sandbox Code Playgroud)
请注意,如果执行此操作,则SomeOtherModel每次加载可能不需要的父实体时都会急切地加载(使用外部联接).一般情况下,我更喜欢始终在映射级别保留默认的延迟加载,并根据情况调整查询.
| 归档时间: |
|
| 查看次数: |
20769 次 |
| 最近记录: |