NHibernate - 必须更改保存顺序以满足数据库约束?

时间:2010-09-23 02:47:02

标签: sql-server nhibernate

我们的数据团队中有人添加了数据库约束,虽然它完全有效且令人满意,但它为NHibernate带来了很大的问题,因为似乎没有办法覆盖NHibernate的保存顺序。

给出一个像这样的(愚蠢的例子)类:

public Person
{  
    public virtual string FirstName { get; set; }  
    public virtual bool IsCurrent { get; set; }  
}

和一个约束,即支持表中只有一条记录可以同时IsCurrent=true。 。

如果我尝试通过设置IsCurrent=false来“弃用”现有记录,并将其替换为带有IsCurrent=true的新记录,我会在Save上获得ADO异常,因为NHibernate尝试首先执行Insert ,违反SQL Server约束,一次只能有一条记录IsCurrent=true

我看到两个选项:

  1. SQL Server是否可以配置为仅在事务结束时检查约束?以下语句(将旧行“更新”到IsCurrent=false将取消约束。
  2. NHibernate的保存顺序(对于相同类型的实例)可以 以任何方式修改或“暗示”?
  3. 谢谢! 杰夫

2 个答案:

答案 0 :(得分:1)

任何一种方法都是可能的;我倾向于#2。如果你打电话:

session.saveOrUpdate(person1);
session.flush();
session.saveOrUpdate(person2);

flush会将SQL语句推送到数据库。我相信这会解决你的问题。 (以上是java Hibernate代码,您的语法可能略有不同)。

答案 1 :(得分:-2)

这里的问题是NHibernate不知道数据库层中的所有数据整合检查。 如果您在编写数据时破解SQL服务器并禁用(短)句点的约束,则可以使用选项1。但这是一个肮脏的解决方案,因为当时正在处理的所有事务都禁用了约束。

在这种特殊情况下,我会使用anonter方法: 没有完整性检查。数据集成基于插入或更新时的触发触发器。除了当前插入或更新的记录之外,触发器负责将所有相关记录的IsCurrent设置为false。当然,你必须处理递归触发器触发,因为使用触发器修改触发器被触发的同一个表中的记录。