我遇到了这种情况。我看到很多开发人员都面临着类似的情况,但我还是想指出一些细节。
我有一个典型的情况,我有一个子对象的集合。我正在向user.contacts属性添加更多联系人。在我的映射lazy = true上该属性。我从不离开调用存储库的方法范围。
我正在使用Windsor WCF Facility。我的理解是,根据我的配置,会话将在请求的生命周期或WcfSession中生存。
如果您需要更多信息,请向我提问。
这是我的wcf服务中的global.asax。
container = new WindsorContainer();
container.AddFacility<AutoTxFacility>();
container.Register(Component.For<INHibernateInstaller>().ImplementedBy<NHibernateInstaller>());
container.AddFacility<NHibernateFacility>();
container.AddFacility<WcfFacility>();
container.Register(
Component.For<IRegistrationService>().ImplementedBy<RegistrationService>().LifestylePerWcfSession(),
Component.For<IAuthService>().ImplementedBy<AuthService>().LifestylePerWcfSession(),
Component.For<IUserRepository>().ImplementedBy<UserRepository>().LifestylePerWcfSession(),
Component.For<IActionWebService>().ImplementedBy<ActionWebService>().Named("ActionWebService").LifestylePerWcfSession(),
Component.For<ISession>().LifeStyle.Singleton.UsingFactoryMethod(x => container.Resolve<ISessionManager>().OpenSession()));
这是我的存储库......
public class UserRepository: IUserRepository
{
Func<ISession> session;
public UserRepository(Func<ISession> _session)
{
session = _session;
}
[Transaction]
public void Store(User user)
{
using (var tx = session())
{
tx.SaveOrUpdate(user);
}
}
[Transaction]
public User GetById(int id)
{
using (var tx=session())
{
return tx.Get<User>(id);
}
}
}
这是我对存储库的调用
public void AddContactsToUser(int userID, IList<User> contacts)
{
var user = userRepository.GetById(userID);
if (user == null)
throw new Exception("User does not exist");
user.AddReferralToUser(contacts.ToArray());
userRepository.Store(user);
}
这是我收到会话关闭错误的地方。
提前谢谢。
答案 0 :(得分:0)
您在ISession上设置了生活方式Singleton。这似乎可能与您的错误不一致,但不应该是...... LifeStyle.PerWcfSession()...或PerWcfOperation()?
会话功能有什么作用? (作为旁注,常见的惯例是将_xxx作为实例成员,将xxx作为函数参数。)
如果你真的拥有相同的会话,那么对Store / SaveOrUpdate的调用是没用的,因为会话已经跟踪了该对象。
您对存储库方法有事务。这不是问题,但是为了使事务有用,整个AddContactsToUser()(或更多)应该在同一个事务中执行。