问题
Using Castle ActiveRecord / NHibernate: Is there a way you can force an ICriterion on all queries on a table?
For example, a good amount of of my tables have a "UserId" column. I might want to ensure that I am always selecting rows for the logged in user. I can easily create an ICriterion object, but I am forced to supply it for different methods: FindAll(), FindFirst(), FindLast() etc.
Is there a way to force a WHERE clause on all queries to a Castle ActiveRecord?
回答1:
I finally found a great solution (using filters). Since Castle AR does not have any native API for mapping to NHibernate filters, this part was pretty much undocumented. So here goes.
This example filter, will make sure you will never get news more than a year old, no matter what kind of query you use on the ActiveRecord. You can probably think of more practical applications for this.
First, create an ActiveRecord "News".
Use the following code before you initialize ActiveRecordStarter.
ActiveRecordStarter.MappingRegisteredInConfiguration += MappingRegisteredInConfiguration;
Castle.ActiveRecord.Framework.InterceptorFactory.Create = () => { return new EnableFiltersInterceptor(); };
Then, add the missing function and class:
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));
}
}
And voila! Queries on News, e.g. FindAll(), DeleteAll(), FindOne(), Exists(), etc. will never touch entries more than a year old.
回答2:
The closest thing would be using filters. See http://ayende.com/Blog/archive/2009/05/04/nhibernate-filters.aspx
来源:https://stackoverflow.com/questions/1358744/nhibernate-creating-a-criteria-which-applies-for-all-queries-on-a-table