我们正在使用Nhibernate v4.0.30319,我们正在使用
Flushmode.Commit
让我们考虑一个例子
Employee
桌子与
IsActive
DB中的列。
在其中一笔交易中,我们正在获取
员工
具有
empId = 100
如下所示:
var employee = session.Get<Employee>(100);
employee.IsActive = false;
它还没有被承诺,甚至还没有被刷新。
我们立即运行查询以获取所有活动的员工。
var activeEmployees = session.CreateCriteria<Employee>()
.Add(Restrictions.Eq("IsActive", true))
.List<Employee>();
现在在
activeEmployees
结果我仍然得到empId=1的员工详细信息,但
IsActive
价值为
false
.
我无法理解为什么这种不一致的行为。如果查询在数据库上运行,那么它应该返回empId-100
IsActive
值“True”,否则如果它在一级缓存上运行,则不应在查询结果中包含empId-100。在这里,它将返回EmpId-1
IsActive
错误的
它为什么会这样?我已经阅读了一些文章和配置细节,但我无法弄清楚这种行为。
我创建了一个控制台应用程序:
员工表:
Nhibernate配置:
if (_sessionFactory == null)
{
var configuration = new Configuration();
// Set connection properties for SQL Server
configuration.SetProperty(NHibernate.Cfg.Environment.ConnectionDriver, typeof(SqlClientDriver).AssemblyQualifiedName);
configuration.SetProperty(NHibernate.Cfg.Environment.ConnectionString, "Data Source=INLT-D72FCSG3\\SQLEXPRESS;Initial Catalog=TestDB;Integrated Security=True;");
configuration.SetProperty(NHibernate.Cfg.Environment.Dialect, typeof(MsSql2012Dialect).AssemblyQualifiedName);
configuration.SetProperty(NHibernate.Cfg.Environment.ShowSql, "true");
configuration.SetProperty(NHibernate.Cfg.Environment.FormatSql, "true");
configuration.SetProperty(NHibernate.Cfg.Environment.Hbm2ddlAuto, "update");
configuration.AddFile("Employee.hbm.xml"); // Add your mapping files
_sessionFactory = configuration.BuildSessionFactory();
}
return _sessionFactory;
执行:
using (var session = NHibernateHelper.OpenSession())
{
session.FlushMode = FlushMode.Commit;
// Start a new transaction
using (var transaction = session.BeginTransaction())
{
// Load employee with Id = 100
var employee = session.Get<Employee>(1);
Console.WriteLine($"Before Update: {employee.Name} - IsActive: {employee.IsActive}");
// Modify the IsActive field to false (this marks the entity as dirty)
employee.IsActive = false;
// The entity is now in the session cache with IsActive = false
Console.WriteLine($"After Update: {employee.Name} - IsActive: {employee.IsActive}");
// Now, we fetch active employees (IsActive = true)
var activeEmployees = session.CreateCriteria<Employee>()
.Add(Restrictions.Eq("IsActive", true))
.List<Employee>();
// Print the active employees (it should still return the modified entity in the session cache)
Console.WriteLine("\nActive Employees (before commit):");
foreach (var emp in activeEmployees)
{
Console.WriteLine($"{emp.Name} - IsActive: {emp.IsActive}");
}
// Commit the transaction to persist changes to the database
transaction.Commit();
}
}
// Simulate a new session for the next query (to see changes after commit)
using (var session = NHibernateHelper.OpenSession())
{
var activeEmployees = session.CreateCriteria<Employee>()
.Add(Restrictions.Eq("IsActive", true))
.List<Employee>();
// Print the active employees after the session is committed
Console.WriteLine("\nActive Employees (after commit):");
foreach (var emp in activeEmployees)
{
Console.WriteLine($"{emp.Name} - IsActive: {emp.IsActive}");
}
}
输出:
NHibernate:
SELECT
employee0_.Id as id1_0_0_,
employee0_.Name as name2_0_0_,
employee0_.IsActive as isactive3_0_0_
FROM
Employee employee0_
WHERE
employee0_.Id=@p0;
@p0 = 1 [Type: Int32 (0:0:0)]
Before Update: John Doe - IsActive: True
After Update: John Doe - IsActive: False
NHibernate:
SELECT
this_.Id as id1_0_0_,
this_.Name as name2_0_0_,
this_.IsActive as isactive3_0_0_
FROM
Employee this_
WHERE
this_.IsActive = @p0;
@p0 = True [Type: Boolean (0:0:0)]
Active Employees (before commit):
John Doe - IsActive: False
Jane Smith - IsActive: True
Bob Brown - IsActive: True
Alice Green - IsActive: True
NHibernate:
SELECT
this_.Id as id1_0_0_,
this_.Name as name2_0_0_,
this_.IsActive as isactive3_0_0_
FROM
Employee this_
WHERE
this_.IsActive = @p0;
@p0 = True [Type: Boolean (0:0:0)]
Active Employees (after commit):
Jane Smith - IsActive: True
Bob Brown - IsActive: True
Alice Green - IsActive: True
谢谢,
纳盖斯雷。