2009-08-31 7 views
2

Utilisation de Castle ActiveRecord/NHibernate: Existe-t-il un moyen de forcer un ICriterion sur toutes les requêtes d'une table? Par exemple, une bonne partie de mes tables ont une colonne "UserId". Je pourrais vouloir m'assurer que je sélectionne toujours des lignes pour l'utilisateur connecté. Je peux facilement créer un objet ICriterion, mais je suis obligé de le fournir pour différentes méthodes: FindAll(), FindFirst(), FindLast() etc.NHibernate: Création d'un critère qui s'applique à toutes les requêtes sur une table

Y at-il un moyen de forcer une clause WHERE sur toutes les requêtes à un Castle ActiveRecord?

Répondre

3

J'ai finalement trouvé une excellente solution (en utilisant des filtres). Comme Castle AR n'a pas d'API native pour le mappage vers les filtres NHibernate, cette partie était à peu près non documentée. Alors voilà. Cet exemple de filtre fera en sorte que vous n'obtiendrez jamais de nouvelles plus d'un an, quel que soit le type de requête que vous utilisez sur ActiveRecord. Vous pouvez probablement penser à des applications plus pratiques pour cela.

D'abord, créez un "News" ActiveRecord.

Utilisez le code suivant avant d'initialiser ActiveRecordStarter.

ActiveRecordStarter.MappingRegisteredInConfiguration += MappingRegisteredInConfiguration; 
Castle.ActiveRecord.Framework.InterceptorFactory.Create =() => { return new EnableFiltersInterceptor(); }; 

Ensuite, ajoutez la fonction manquante et classe:

void MappingRegisteredInConfiguration(Castle.ActiveRecord.Framework.ISessionFactoryHolder holder) 
{ 
    var cfg = holder.GetConfiguration(typeof (ActiveRecordBase)); 

    var typeParameters = new Dictionary<string, IType> 
            { 
            {"AsOfDate", NHibernateUtil.DateTime} 
            }; 

    cfg.AddFilterDefinition(new FilterDefinition("Latest", "", typeParameters)); 

    var mappings = cfg.CreateMappings(Dialect.GetDialect(cfg.Properties)); 

    var newsMapping = cfg.GetClassMapping(typeof (News)); 
    newsMapping.AddFilter("Latest", ":AsOfDate <= Date"); 
} 


public class EnableFiltersInterceptor : EmptyInterceptor 
{ 
    public override void SetSession(ISession session) 
    { 
     session.EnableFilter("Latest").SetParameter("AsOfDate", DateTime.Now.AddYears(-1)); 
    } 
} 

Et le tour est joué! Requêtes sur News, par ex. FindAll(), DeleteAll(), FindOne(), Exists(), etc. ne toucheront jamais les entrées datant de plus d'un an.

1

Le plus proche serait d'utiliser des filtres. Voir http://ayende.com/Blog/archive/2009/05/04/nhibernate-filters.aspx

+0

Cela semble être une bonne solution, mais je ne peux pas comprendre s'il est possible d'utiliser ces filtres avec Castle ActiveRecord. – mbp

+0

http://groups.google.com/group/castle-project-devel/browse_thread/thread/ce94f492615e0d52/c721a7abb0a1f1a7 Je ne pense pas que cela ait jamais été implémenté ... vous aurez l'ISession actuelle et activez les filtres vous-même –

+0

IIRC vous pouvez obtenir l'ISession en cours à partir de ActiveRecordMediator.GetSessionFactoryHolder(). CreateSession (typeof (ActiveRecordBase)) –

Questions connexes