0

テーブルにレコードを挿入していますが、挿入時に SortOrder フィールドを SELECT MAX(SortOrder) + 1 FROM Category WHERE SiteID = @SiteID に設定できるようにしたいと考えています。これを行う最も簡単な方法は何ですか?

ここに私のデータ構造があります:
カテゴリ
ID
SiteID
SortOrder
Name

Fluent NHibernate と Linq to NHibernate を使用しています。助けてくれてありがとう!

4

1 に答える 1

1

わかりました、ここに2つの方法があります。SQL Serverを使用しているため、最も単純な場合はNHibernateを使用しない場合があります...次のように、テーブルにINSTEADOFINSERTトリガーを作成するだけで済みます。

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

この最初のシナリオでは、SortOrder列を読み取り専用としてNHibernateマップします(流暢なnhibernateクラスマップSortOrderプロパティに.ReadOnly()を追加するだけです)。

2番目の方法は、インターセプターと呼ばれる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);
        }
    }

私の意見では、この種の古典的なトリガー操作はおそらくデータベース上に存在するはずであり、最初のオプションを選択します...

于 2010-06-19T05:19:41.243 に答える