Как выполнить запрос времени выполнения, используя Linq to NHibernate - PullRequest
0 голосов
/ 13 апреля 2010

Я вставляю запись в свою таблицу, но я хочу иметь возможность установить Поле SortOrder для вставки в SELECT MAX (SortOrder) + 1 ОТ категории ГДЕ SiteID = @SiteID. Какой самый простой способ сделать это?

Вот моя структура данных:
Категория
ID
SiteID
SortOrder
Имя

Я использую Fluent NHibernate и Linq для NHibernate. Спасибо за любую помощь!

1 Ответ

1 голос
/ 19 июня 2010

Хорошо, вот 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 как доступный только для чтения (просто добавьте .ReadOnly () в свойство SortOrder для карты класса nhibernate)

Второй способ - использовать встроенную функцию 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);
        }
    }

По моему мнению, такая классическая операция триггера, вероятно, должна существовать в базе данных, и я бы выбрал первый вариант ...

...