我正在使用NHibernate 2.1。我成功地将记录插入表中,但我有一个需要在插入时计算的SortOrder列。公式大致为:
SortOrder =(SELECT(MAX(SortOrder)+ 1)FROM MyTable WHERE CategoryID = @CategoryID)
如何在插入时在NHibernate中完成此操作?通常我使用存储过程,我会在那里包含它。
感谢您的帮助!
答案 0 :(得分:0)
我不知道通过映射文件执行您所要求的方法。我不认为有一个。
我如何处理问题的方法是插入一个PreInsertListener并在那里执行你在问题中提供的select语句,以便在保存实体之前检索SortOrder应答的值。
以下是粗略的看法:
public class NHibernateEventListeners : IPreInsertEventListener
{
public bool OnPreInsert(PreInsertEvent auditEvent)
{
var audit = auditEvent.Entity as YourEntityTypeHere;
if (audit == null)
return false;
int sortOrderValue =
(int)auditEvent.Session.CreateCriteria<YourEntityTypeHere>()
.SetProjection(Projections.Max("SortOrder"))
.Add(Restrictions.Eq("CategoryID", CatID)).UniqueResult();
SetValue(auditEvent.Persister, auditEvent.State, "SortOrder", sortOrderValue + 1);
audit.DateCreated = sortOrderValue + 1;
return false;
}
}
答案 1 :(得分:0)
你仍然可以使用带有nhibernate的存储过程。您需要在xml映射文件中实现<sql-insert>
,<sql-update>
和<sql-delete>
来执行任何专门的CRUD。我认为根据你的情况,这将是你最好的选择。
答案 2 :(得分:0)
在类映射文件中,您可以为列/属性指定SQL公式。使用XML映射文件:
<property name="SortOrder" formula=" (SELECT (MAX(SortOrder) + 1) FROM MyTable WHERE CategoryID = @CategoryID)"/>
或者,如果您使用流畅的映射:
Map(x => x.SortOrder).FormulaIs(" (SELECT (MAX(SortOrder) + 1) FROM MyTable WHERE CategoryID = @CategoryID)");
看看是否有效。
答案 3 :(得分:0)
您可以在数据库中编写触发器,但要注意此方法的问题,因为NHibernate不会意识到此计算字段中的更改。您必须在保存后使用Flush()方法并在其后使用Refresh(your_data_object)方法。
关于在“NHibernate in Action”一书中处理触发器有一个很好的详细解释:“9.2.4使用触发器”。