c# - 如何告诉 NHibernate 触发器更新了另一个表?

标签 c# nhibernate exception triggers

我在使用 NHibernate 时遇到了 TooManyRowsAffectedException,我已经看到通过注入(inject)不同的批处理程序来解决这个问题,就像这里 TooManyRowsAffectedException with encrypted triggers ,或者通过修改数据库中的触发器以使用 SET NOCOUNT ON(我不能使用这个,因为我不想修改数据库——它非常复杂,有一百多个表都相关联,我不不想弄乱它,因为其他应用程序使用它)。我不明白的是为什么会发生这种异常。我所做的就是我有一个 Sample 对象,它有几个我检查的值,如果这些值符合给定的标准,我将 Sample.IsDone 行设置为“Y”(在我们的数据库中,所有 bool 值都由一个字符 Y 或 N)。代码非常简单:

IQueryable<Sample> samples = session.Query<Sample>().Where(s =­­> s.Value == desiredValue);
foreach (Sample sample in samples)
{
  sample.IsDone = 'Y';
  session.Flush(); // Throws TooManyRowsAffectedException
}
session.Flush(); // Throws TooManyRowsAffectedException

无论我将它放在循环内部还是外部,Flush 调用都会抛出异常。是我做错了什么,还是只与数据库的制作方式有关?我尝试在 Flush() 之前对示例调用 SaveOrUpdate(),但它没有改变任何东西。我知道我可以解决此异常,但我更愿意了解问题的根源。

注意:在异常情况下,它告诉我实际行数是 2,预期是 1。为什么它更新 2 行,因为我只更改了 1 行?

感谢大家的帮助!

编辑:

我能够找出原因是因为当更新样本时,数据库中有一个触发器更新 Container 表中的一行 (Containers contain Samples)。有没有一种方法可以配置 NHibernate,使其了解此触发器并期望更新正确数量的行?

最佳答案

我发现的唯一解决方法是在下面使用 Fluent NHibernate 的代码片段中。它很难看,因为它将 SQL 硬编码到您的映射中,但它确实有效。 Check 属性设置为 None 以便忽略计数。我不知道您是否可以使用直接的 HBM 文件来完成此操作,但可能有办法。如果 NHibernate(或 Fluent NH)中有一个配置选项来设置预期的更新行数或在需要时忽略它,那就太好了。

public class OrderMap : ClassMap<Order>
{
    public OrderMap()
    {
        Id(c => c.Id, "order_id").GeneratedBy.Native();

        Table("order");

        Map(c => c.GroupId, "group_id");
        Map(c => c.Status, "status");
        Map(c => c.LocationNumber, "location");

        SqlInsert("insert into order (group_id, status, location) values (?, ?, ?)").Check.None();
        SqlUpdate("update order set group_id = ?, status = ?, location = ? where order_id = ?")).Check.None();
        SqlDelete("delete order where order_id = ?").Check.None();
    }
}

编辑: 对于那些不了解 Fluent NHibernate 或喜欢手动生成 HBM 文件的不幸人士,这里是此示例映射的 HBM 文件:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
  <class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="Your.DomainModel.Entities.Order, Your.DomainModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="order">
    <id name="Id" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
      <column name="order_id" />
      <generator class="identity" />
    </id>
    <property name="GroupId" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="group_id" />
    </property>
    <property name="Status" type="System.Int16, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="status" />
    </property>
    <property name="LocationNumber" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="loc_num" />
    </property>
    <sql-insert check="none">insert into order (group_id, status, location) values (?, ?, ?)</sql-insert>
    <sql-update check="none">update order set group_id = ?, status = ?, location = ? where order_id = ?</sql-update>
    <sql-delete check="none">delete order where order_id = ?</sql-delete>
  </class>
</hibernate-mapping>

关于c# - 如何告诉 NHibernate 触发器更新了另一个表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6583583/

相关文章:

java - 替换 JAR 文件中的 XML 文件

c# - 如何从文本文件或 cdr 文件(包括空格)中删除换行符或换行符?

c# - 编译表达式树的误解?

C#数字键决定三个数组操作中的哪一个

c++ - Windows Mobile 在 `new` 失败时返回 0

java.net.SocketException : Network is unreachable: connect 异常

c# - 有效跳过二维字符串数组中的空白行

c# - NHibernate 在删除之前更新行?

c# - ASP.NET 4 MVC 十进制溢出与 Fluent NHibernate 和 SQL Server 2008 RC2

c# - NHibernate ICriteria - 排序是否允许空值?