我目前正在使用nHibernate并且遇到一个问题,即两个对象单独加载但在数据库中表示相同的实体没有相同的引用。
请参阅以下代码部分:
CrudRepository<Customer> cr1 = new CrudRepository<Customer>();
Customer c1 = cr1.GetById(new Guid("0D19B0F0-CA41-4D4B-9FB9-9CF600F86A4B"));
CrudRepository<Customer> cr2 = new CrudRepository<Customer>();
Customer c2 = cr2.GetById(new Guid("0D19B0F0-CA41-4D4B-9FB9-9CF600F86A4B"));
if (c1.Equals(c2))
MessageBox.Show("SAME!"); // True.
if (c1.GetHashCode().Equals(c2.GetHashCode()))
MessageBox.Show("SAME!"); // True.
if (c1 == c2)
MessageBox.Show("SAME!"); // False.
我对nHibernate文档的解释让我相信,一旦你重写了Equals()和GetHashCode()方法,nHibernate就可以将实体加载到同一个引用中。
这是我所指的界线:
这仅适用于在两个不同的ISession中加载这些对象的情况, 因为NHibernate只保证身份 (a == b,默认实现 Equals())在单个内部 的Isession 的!
我知道(c1 == c2)正在比较在不同时间加载的对象的引用。 然而,我认为(并希望)nHibernate会自动跟踪预加载的引用并相应地更新它们。
这不是真的吗?
或者我做错了什么?
谢谢:)
注意:我使用单例模式在整个应用程序中保持相同的会话。
编辑:每次执行CRUD任务时,我都会使用此NHibernateHelper类来获取同一会话构建器的单个实例。这是一段代码示例。
public T GetById(Guid guid)
{
using (ISession session = NHibernateHelper.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
return session.Get<T>(guid);
}
}
这是我的助手班:
public class NHibernateHelper
{
private static ISessionFactory sessionFactory;
private static ISessionFactory SessionFactory
{
get
{
if (sessionFactory == null)
{
var configuration = new Configuration();
configuration.Configure();
configuration.AddAssembly(typeof(Customer).Assembly);
sessionFactory = configuration.BuildSessionFactory();
}
return sessionFactory;
}
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
}
答案 0 :(得分:2)
您正在为每个请求创建一个新会话(这是您的NHibernateHelper.OpenSession()
方法所做的),而nHibernate仅保证一个会话中的引用相等。一旦确定您的请求在同一会话中,两次调用的结果将是同一个对象。