C# 从一个会话检索对象并在另一个会话中更新nHibernate
我需要更新客户的详细信息。为此,我必须从存储库的另一个会话中检索实体,并在服务中更新该实体。执行此操作时,我会收到一条错误消息,上面说: 该操作对于登记的当前状态无效 但是,如果我更新了实体而没有从数据库中检索它,那么一切都正常 这就是我试图在服务中更新的方式C# 从一个会话检索对象并在另一个会话中更新nHibernate,c#,nhibernate,C#,Nhibernate,我需要更新客户的详细信息。为此,我必须从存储库的另一个会话中检索实体,并在服务中更新该实体。执行此操作时,我会收到一条错误消息,上面说: 该操作对于登记的当前状态无效 但是,如果我更新了实体而没有从数据库中检索它,那么一切都正常 这就是我试图在服务中更新的方式 Customer customer = customerService.getById(customer_payment.customer_id); customer.deductBalance(customer_payment.di
Customer customer = customerService.getById(customer_payment.customer_id);
customer.deductBalance(customer_payment.discount_received);
customerService.updateCustomerDetails(customer);
这是更新实体的“我的存储库”:
using (ISession session = SessionFactory.OpenSession)
{
using(ITransaction t = session.BeginTransaction())
{
session.SaveOrUpdate(customer);
t.Commit();
}
}
这是我的函数,返回给定ID的实体:
顾客
using (ISession session = SessionFactory.OpenSession)
{
customer = session.Get<Customer>(customer_id);
}
return customer;
每次打开一个新的会话是一种好方法,还是应该在会话工厂中使用单例模式?在使用其他会话更新之前,将
客户
从第一个会话中分离出来。您必须在存储库上公开execute
方法,或者必须在存储库外部公开ISession
Customer customer = customerService.getById(customer_payment.customer_id);
customerService.Evict(customer);
//OR
customerRepository.Evict(customer);
//OR
customerService.Session.Evict(customer);
//OR something similar...
customer.deductBalance(customer_payment.discount_received);
customerService.updateCustomerDetails(customer);
请参阅以下内容:
编辑(用于更新)
每次打开一个新会话是一种好方法,还是应该在SessionFactory中使用Singleton模式
这实际上是基于意见的问题;但是建议您的会话应该是短期的
也就是说,您可以为每个数据库操作创建新会话。但是这样做,您将丢失许多ORM特性,如会话级缓存、延迟加载、更改跟踪(UoW)等
您可以选择在请求级别移动UoW(即每个请求的ISession
),这样您就可以利用ORM功能;但也有其他与之相关的问题。请参阅以下内容:
OpenSession属性中有什么?您需要确保附加到现有会话,而不是创建/打开新会话。@DenisIvin先生,我已编辑了我的问题。你能看一下吗?我最后又补充了一个问题。很抱歉,因为我最初的意图是另一个问题。你能帮我解决第二个问题吗。
Customer customer = customerService.getById(customer_payment.customer_id);
customerService.Evict(customer);
//OR
customerRepository.Evict(customer);
//OR
customerService.Session.Evict(customer);
//OR something similar...
customer.deductBalance(customer_payment.discount_received);
customerService.updateCustomerDetails(customer);