使用 SQL Server 触发器时的 Nhibernate 缓存问题
我正在使用 Nhibernate 和 Fluent,在业务应用程序中保存 SQL Server 2008 Express 数据库。
我有一个名为 Receipt 的类,其中包含一个包含许多名为 ReceiptItems 的对象的列表。 用户可以创建收据,向其添加收据项,并对其进行编辑,只要其未标记为“已完成”。 这部分工作正常并正确保存到数据库。 现在问题是:
我在 sql 表 Receipt 上还有一个触发器,如果 insert.Finished 为 true,则该触发器会触发。 触发器从“供应商表”中获取新价格,并更新所有 ReceiptItems 的价格, 在 ReceiptItems 表中。
打电话时 会话.SaveorUpdate(值) 进而 transaction.Commit()
后者会导致异常: 陈旧对象状态异常 行已被 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 出现问题时 实体的 SQL INSERT 或 UPDATE 其中定义了生成 属性,它立即发出 之后选择检索 生成的值。
标记为生成的属性必须 另外是不可插入的并且 不可更新。
由于我是新来的..,最后一句是否意味着我无法使用 nhibernate 插入或更新值?
I am using Nhibernate with Fluent, to persist a SQL Server 2008 express database in a business application.
I have a class named Receipt which contains a list with many objects named ReceiptItems.
The user can create a receipt, add Receiptitems to it, and edit it as long as its not marked Finished.
This part works well and saves to the db correctly.
Now for the problem:
I also have a trigger on the sql table Receipt, that fires if the inserted.Finished is true.
The trigger fetches new prices from the "supplier table", and updates the prices for all ReceiptItems,
in the ReceiptItems table.
When calling
session.SaveorUpdate(value)
and then
transaction.Commit()
the latter causes the exception:
StaleObjectStateException
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) in ReceiptItems
Removing the trigger ofcourse fixes the problem, but i need it to update the prices. Is there any way for nhibernate to ignore the
error, and refresh its cache after the trigger fires?
straightforward class example definitions with Fluent mappings:
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 );
}
}
Thank you very much !
UPDATE:
I've found a nhibernate property, which does exactly what i need, as the Price and Discount values have to be generated by the trigger:
5.6. Generated Properties Generated properties are properties which have
their values generated by the
database. Typically, Hibernate
applications needed to refresh objects
which contain any properties for which
the database was generating values.
Marking properties as generated,
however, lets the application delegate
this responsibility to Hibernate.
Essentially, whenever Hibernate issues
an SQL INSERT or UPDATE for an entity
which has defined generated
properties, it immediately issues a
select afterwards to retrieve the
generated values.Properties marked as generated must
additionally be non-insertable and
non-updateable.
As im new at this.., does the last sentance mean, that i can't insert or update the values with nhibernate?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在触发器中使用
SET NOCOUNT ON
可以抑制触发器处理中的(xx 行受影响)
“虚拟”结果集。示例问题:带有加密触发器的TooManyRowsAffectedException
Use
SET NOCOUNT ON
in the trigger to suppress(xx rows affected)
"dummy" result sets from trigger processing.Example SO question: TooManyRowsAffectedException with encrypted triggers