2010-04-13 133 views
0

我正在向我的表中插入一条记录,但我希望能够在插入时将我的 SortOrder字段设置为SELECT MAX(SortOrder)+ 1 FROM Category Where SiteID = @SiteID。这样做最简单的方法是什么?如何使用Linq执行NHibernate的执行时间查询

这里是我的数据结构:
类别
ID
SITEID
SortOrder的
名称

我使用功能NHibernate和LINQ to NHibernate的。谢谢你的帮助!

+1

什么是数据库?在SQL中,您可以将该列设置为自动增量列,并且您所描述的内容默认情况下会发生。 其他数据库服务器也会做类似的事情。没有必要的代码来实现它。插入时,您不提供SortOrder的值。 – Cheeso 2010-06-18 22:12:42

+0

它是SQL Server,但表中有子集,这就是我通过SiteID进行筛选的原因。 – 2010-06-19 03:40:19

回答

1

好的,这里有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); 
     } 
    } 

在我看来这种经典的触发操作的可能应该住在数据库上,我会用第一个选项去...