我有一个父子关系,父母没有对孩子的引用-像这样:
class Child
{
int Id { get; set;
Parent Parent { get; set; }
// + other stuff
}
class Parent
{
int Id { get; set; }
// + other stuff
}
在数据库中,这仅意味着该Child
表具有一ParentID
列。该列可以为Parent
null-即可以有一个-less Child
。
我正在使用Fluent约定来映射域,但是对此关系有一个替代,以便我们可以同时更新Child
和创建一个新Parent
的:
public class ChildOverride : IAutoMappingOverride<Child>
{
public void Override(AutoMapping<Child> mapping)
{
mapping.References(x => x.Parent).Cascade.All();
}
}
当我们Parent
向现有对象添加新的Child
并且立即需要(在事务处理中)读取该父对象的ID时,就会出现问题,例如:
existingChild.CreateParent(parameters);
session.Save(existingChild);
Debug.WriteLine(existingChild.Parent.Id);
它只是打印0
而不是给我新父母的ID-我以为是Cascade.All()
……级联。错了吗
如果我在访问Id之前提交了事务,那么一切都很好,或者如果我也明确保存了同样可行的新Parent,例如
// This works
existingChild.CreateParent(parameters);
session.Save(existingChild);
transaction.Commit();
Debug.WriteLine(existingChild.Parent.Id);
// This also works
existingChild.CreateParent(parameters);
session.Save(existingChild);
session.Save(existingChild.Parent);
Debug.WriteLine(existingChild.Parent.Id);
有什么方法可以更改覆盖,以便保存子对象将允许立即访问父ID?(还是我做错了什么?)
这样做的好处是,所有功能均正常运行。而且您的映射是正确的。因为如果此代码段有效...
// This works
existingChild.CreateParent(parameters);
session.Save(existingChild);
transaction.Commit();
...这个概念也行得通。为什么?到底是什么?为什么Commit()
帮助解决这个问题?
好吧,因为ISession
是一个抽象,所以它是虚拟的持久性存储。在我们调用时,它不会执行任何SQL语句session.Save()
。它仅保留所有信息(在该会话期间收集)并仅执行SQL WRITE语句
但是更好更精确的是引用doc:
ISession会不时执行将ADO.NET连接状态与保存在内存中的对象状态同步所需的SQL语句。默认情况下,此过程在以下几点进行刷新
...
除非您明确声明
Flush()
,否则绝对不能保证Session执行ADO.NET调用的时间,仅保证它们执行的顺序。但是,NHibernate确实保证了ISession.Find(..)方法将永远不会返回过时的数据。他们也不会返回错误的数据。可以更改默认行为,以便减少刷新的频率。所述FlushMode类定义了三种不同的模式:仅在提交时齐平(并且使用NHibernate的ITransaction API仅当),自动地使用该解释常规冲洗(只会明确的NHibernate ITransaction内部工作),或者从未除非冲洗冲洗()是显式调用。最后一种模式对于长时间运行的工作单元很有用,在这种情况下,ISession长时间保持打开和断开状态(请参见第11.4节“乐观的并发控制”)。
并且有答案。该FlushMode
设置:
public enum FlushMode
{
Unspecified = -1,
Never = 0,
Commit = 5,
Auto = 10,
Always = 20,
}
因此,如果FlushMode为Commit
-仅事务提交触发session.Flush()
但是我们可以随时自己做:
// This works
existingChild.CreateParent(parameters);
session.Save(existingChild);
session.Flush();
现在父级将具有ID-因为会话状态刚刚转换为SQL WRITE操作...
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句