使用SQL Server触发器时出现Nhibernate缓存问题

时间:2010-07-12 22:31:17

标签: c# sql-server nhibernate fluent-nhibernate triggers

我正在使用Nhibernate和Fluent,将SQL Server 2008 Express数据库保存在业务应用程序中。

我有一个名为Receipt的类,它包含一个包含许多名为ReceiptItems的对象的列表。 用户可以创建收据,向其添加Receiptitems,并在其未标记为已完成时进行编辑。 这部分工作正常并正确保存到数据库。 现在出现问题:

我在sql表的Receipt上也有一个触发器,如果​​inserted.Finished为true则触发。 触发器从“供应商表”中获取新价格,并更新所有ReceiptItem的价格, 在ReceiptItems表中。

打电话时 session.SaveorUpdate(值) 然后 器transaction.commit()

后者导致异常: StaleObjectStateException 在ReceiptItems

中,行已被另一个事务更新或删除(或未保存的值映射不正确)

删除事件触发器可以解决问题,但我需要它来更新价格。 nhibernate有没有办法忽略它 错误,并在触发器触发后刷新其缓存?

使用Fluent映射的直接类示例定义:

 public class Receipt
    {

        public Receipt() { }
        /// <summary>Identificator/// </summary>
        public virtual int Id { get; private set; }
        /// <summary> if finished true, cant edit data/// </summary>
        public virtual Boolean Finished { get; set; }
        /// <summary>Items of this Receipt/// </summary>
        public virtual IList<ReceiptItems> Items{ get; set; }
    }

    /// <summary>Mapping for NHibernate Fluent/// </summary>
    public class ProdajaMap : ClassMap<Prodaja>
    {

        public ReceiptMap()
        {
            Table("Receipt");
            OptimisticLock.All();
            DynamicUpdate();
            Id(x => x.Id);
            Map(x => x.Finished);
            HasMany<ReceiptItems>(x => x.Items).AsBag().KeyColumn("Receipt_ID");
        }
    }

public class ReceiptItem
    {

        public ReceiptItem() { }

        public virtual int Id { get; private set; }
        /// <summary>Id of the Receipt/// </summary>
        public virtual int Receipt_ID{ get; set; }

        /// <summary>Supplier price/// </summary>
        public virtual decimal Price{ get; set; }
        /// <summary>Supplier discount/// </summary>
        public virtual decimal Discount { get; set; }
    }

    /// <summary>Mapping for NHibernate Fluent/// </summary>
    public class ReceiptItemMap : ClassMap<ReceiptItem>
    {
        public ReceiptItemMap()
        {
            Table("ReceiptItems");
            OptimisticLock.All();
            DynamicUpdate();
            Id(x => x.Id);
            Map(x => x.Receipt_ID).Column("Receipt_ID");
            Map(x => x.Price);
            Map(x => x.Discount );

        }
    }

非常感谢!

更新

我发现了一个nhibernate属性,它完全符合我的需要,因为价格和折扣值必须由触发器生成:

  

5.6。生成的属性生成的属性是具有的属性   他们的价值由   数据库。通常,Hibernate   刷新对象所需的应用程序   其中包含任何属性   数据库正在生成值。   将属性标记为已生成,   但是,让应用程序委托   这对Hibernate负有责任。   基本上,每当Hibernate发布时   实体的SQL INSERT或UPDATE   已定义生成的   属性,它立即发出一个   之后选择以检索   生成的值。

     

标记为已生成的属性必须   另外是不可插入的   不可更新。

正如我刚才所说的那样,最后的发送是否意味着,我无法使用nhibernate插入或更新值?

1 个答案:

答案 0 :(得分:1)

在触发器中使用SET NOCOUNT ON来禁止触发处理中的(xx rows affected)“虚拟”结果集。

示例SO问题:TooManyRowsAffectedException with encrypted triggers