如何使用Linq到NHibernate执行执行时查询

时间:2010-04-13 18:28:42

标签: nhibernate fluent-nhibernate linq-to-nhibernate

我正在将记录插入到我的表中,但我希望能够设置我的记录 插入到SELECT MAX(SortOrder)+ 1 FROM FROM的SortOrder字段 WHERE SiteID = @SiteID。这样做最简单的方法是什么?

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

我正在使用Fluent NHibernate和Linq来NHibernate。谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

好的,这里有两种方法。最简单的可能不涉及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);
        }
    }

在我看来,这种经典的触发操作可能应该存在于数据库中,我会选择第一个选项......