Ok, voici 2 façons. Le plus simple ne peut impliquer NHibernate puisque vous utilisez SQL Server ... Vous pouvez tout simplement créer un déclencheur INSTEAD OF INSERT sur la table, comme ceci:
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
Dans ce premier scénario vous simplement NHibernate carte du SortOrder colonne en lecture seule (il suffit d'ajouter .ReadOnly() sur la propriété SortOrder de la classe nhibernate courante).
La seconde méthode consisterait à utiliser la fonction intégrée de NHibernate appelée intercepteurs. Avec un intercepteur, vous pouvez exécuter le code que vous voulez juste au moment où NHibernate génère normalement du SQL pour exécuter une action DML. Les informations de création ci-dessous auto-inserts, mais serait très similaire à ce que vous auriez besoin. IInsertLoggable est une interface personnalisée qui répertorie simplement les propriétés/colonnes d'intérêt pour l'interception.
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);
}
}
À mon avis, ce genre d'opération de déclenchement classique devrait probablement vivre sur la base de données et je partirais avec la première option ...
ce qui est la base de données? dans SQL, vous pouvez simplement faire de la colonne une colonne d'auto-incrémentation, et ce que vous décrivez se produit par défaut. D'autres serveurs de base de données font des choses similaires. Il n'y a pas de code requis pour y arriver. Lors de l'insertion, vous ne fournissez pas de valeur pour SortOrder. – Cheeso
Il s'agit de SQL Server, mais il existe des sous-ensembles dans la table, ce qui explique pourquoi j'ai filtré par SiteID. –