我正在向我的表中插入一条记录,但我希望能够在插入时将我的 SortOrder 字段设置为 SELECT MAX(SortOrder) + 1 FROM Category WHERE SiteID = @SiteID。最简单的方法是什么?
这是我的数据结构:
Category
ID
SiteID
SortOrder
Name
我正在使用 Fluent NHibernate 和 Linq to NHibernate。谢谢你的帮助!
我正在向我的表中插入一条记录,但我希望能够在插入时将我的 SortOrder 字段设置为 SELECT MAX(SortOrder) + 1 FROM Category WHERE SiteID = @SiteID。最简单的方法是什么?
这是我的数据结构:
Category
ID
SiteID
SortOrder
Name
我正在使用 Fluent NHibernate 和 Linq to NHibernate。谢谢你的帮助!
好的,这里有2种方法。最简单的可能不涉及 NHibernate,因为您使用的是 SQL Server ...您可以在表上创建一个 INSTEAD OF INSERT 触发器,如下所示:
CREATE TRIGGER tgINSCategory ON Category INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON
INSERT INTO Category (SiteID, Name, SortOrder)
SELECT SiteID, Name,
ISNULL((SELECT MAX(c.SortOrder)
FROM Category c INNER JOIN INSERTED i ON c.SiteID = i.SiteID), 0) + 1
FROM INSERTED
END
在第一个场景中,您只需 NHibernate 将 SortOrder 列映射为只读(只需在流畅的 nhibernate 类映射 SortOrder 属性上添加 .ReadOnly() )。
第二种方法是使用 NHibernate 的内置功能,称为拦截器。使用拦截器,您可以在 NHibernate 通常生成 SQL 以执行 DML 操作时运行您喜欢的任何代码。以下自动插入创建信息,但与您需要的非常相似。IInsertLoggable 是一个自定义接口,它简单地列出了拦截感兴趣的属性/列。
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
public class InsertDefaults : EmptyInterceptor {
private const string CREATED_BY = "CreatedById";
private Hashtable GetInsertLoggablePropertyIndexes(string[] Properties) {
Hashtable result = new Hashtable();
for (int i = 0; i < Properties.Length; i++) {
if (Properties[i] == CREATED_BY) {
result.Add(CREATED_BY, i);
break;
}
}
return result;
}
public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types) {
if (entity is IInsertLoggable) {
Hashtable indexes = GetInsertLoggablePropertyIndexes(propertyNames);
state[(int)indexes[CREATED_BY]] = currentUser;
PropertyInfo createdByProp = entity.GetType().GetProperty(CREATED_BY);
if (createdByProp != null)
createdByProp.SetValue(entity, currentUser, null);
}
return base.OnSave(entity, id, state, propertyNames, types);
}
}
在我看来,这种经典的触发器操作可能应该存在于数据库中,我会选择第一个选项......