NHibernate: Membuat kriteria yang berlaku untuk semua kueri pada tabel

Menggunakan Castle ActiveRecord/NHibernate: Apakah ada cara Anda dapat memaksakan Icriterion pada semua kueri di atas meja?

Misalnya, sebagian besar tabel saya memiliki kolom "UserId". Saya mungkin ingin memastikan bahwa saya selalu memilih baris untuk pengguna yang masuk. Saya dapat dengan mudah membuat objek Icriterion, tetapi saya terpaksa menyediakannya untuk metode yang berbeda: FindAll(), FindFirst(), FindLast() dll.

Apakah ada cara untuk memaksakan klausa WHERE pada semua pertanyaan ke Castle ActiveRecord?


person mbp    schedule 31.08.2009    source sumber


Jawaban (2)


Saya akhirnya menemukan solusi hebat (menggunakan filter). Karena Castle AR tidak memiliki API asli untuk memetakan ke filter NHibernate, bagian ini hampir tidak terdokumentasi. Jadi begini.

Contoh filter ini, akan memastikan Anda tidak akan pernah mendapatkan berita lebih dari satu tahun, apa pun jenis kueri yang Anda gunakan di ActiveRecord. Anda mungkin bisa memikirkan penerapan yang lebih praktis untuk ini.

Pertama, buat "Berita" ActiveRecord.

Gunakan kode berikut sebelum Anda menginisialisasi ActiveRecordStarter.

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

Kemudian, tambahkan fungsi dan kelas yang hilang:

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));
    }
}

Dan voila! Pertanyaan tentang Berita, mis. FindAll(), DeleteAll(), FindOne(), Exists(), dll. tidak akan pernah menyentuh entri yang berumur lebih dari satu tahun.

person mbp    schedule 03.09.2009

Hal yang paling dekat adalah menggunakan filter. Lihat http://ayende.com/Blog/archive/2009/05/04/nhibernate-filters.aspx

person Mauricio Scheffer    schedule 31.08.2009
comment
Ini sepertinya solusi yang bagus, namun saya tidak tahu apakah filter ini dapat digunakan dengan Castle ActiveRecord. - person mbp; 02.09.2009
comment
groups.google.com/group/castle-project- devel/browse_thread/ Saya rasa ini belum pernah diterapkan... Anda akan mendapatkan ISession saat ini dan mengaktifkan sendiri filternya - person Mauricio Scheffer; 02.09.2009
comment
IIRC Anda bisa mendapatkan ISession saat ini dari ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(ActiveRecordBase)) - person Mauricio Scheffer; 02.09.2009
comment
Mengaktifkan filter tampaknya mungkin, tetapi cara membuatnya lebih merupakan masalah. - person mbp; 03.09.2009