2015-04-30 17 views
0

一週前我問了how to propagate a parameter for joins in a ORM。建議的解決方案看起來很有前途 - 使用NHibernate過濾器。下面是我在做什麼:無法獲得NHibernate篩選器來過濾實體 - 我是否缺少概念?

過濾器類:

public class VersionFilter : FilterDefinition 
{ 
    public static readonly string Name = typeof(VersionFilter).AssemblyQualifiedName; 

    public static readonly string Parameter = "AsOf"; 

    private static readonly string SqlParameter = ":" + Parameter; 
    private static readonly string Condition 
     = " ISNULL(" + SqlParameter + ") AND (ISNULL(ValidTo))" + 
      " OR (ValidFrom < " + SqlParameter + " AND " + SqlParameter + " <= ValidTo)" 
    ; 
    private static readonly IDictionary<string, IType> ParameterTypes = 
     new Dictionary<string, IType> 
     { 
      {Parameter, NHibernateUtil.Int64} 
     } 
    ; 

    public VersionFilter(): base(Name, Condition, ParameterTypes, true) 
    { 
    } 
} 

在主營:

public class Program 
{ 
    static void Main(string[] args) 
    { 
     log.Info("VersionedDataModel1.Program::start"); 
     try 
     { 
      var cfg = new Configuration(); 
      cfg.Configure(); 
      cfg.AddFilterDefinition(new VersionFilter()); 

      var types = DomainClasses(typeof(Program).Assembly, "VersionedDataModel1.Domain"); 

      foreach (Type type in types) 
      { 
       cfg.AddInputStream(HbmSerializer.Default.Serialize(type)); 
      } 
      var sessionFactory = cfg.BuildSessionFactory(); 

      { 
       var schema = new SchemaExport(cfg); 
       schema.Drop(false, true); 
       schema.Execute(false, true, false); 
       //new SchemaExport(cfg).Drop(false, true); 
       //new SchemaExport(cfg).Execute(false, true, false); 
       //new SchemaUpdate(cfg).Execute(false, true); 
      } 
     } 
    } 
} 

一個實體類:

[Class] 
public class Store : BaseEntity 
{ 
    private ICollection<Product> _products = new List<Product>(); 
    private ICollection<Employee> _staff = new List<Employee>(); 

    [Property(NotNull = true)] 
    public virtual string Name { get; set; } 

    [Set(0, Table = "ProductsInStore", Lazy = CollectionLazy.False, Cascade = "none")] 
    [Key(1, Column = "StoreId")] 
    [ManyToMany(2, Column = "ProductId", ClassType = typeof(Product))] 
    public virtual ICollection<Product> Products { get { return _products; } set { _products = value; } } 

    [Key(1, Column = "StoreId")] 
    [OneToMany(2, ClassType = typeof(Employee))] 
    public virtual ICollection<Employee> Staff { get { return _staff; } set { _staff = value; } } 

    public virtual void AddProduct(Product product) 
    { 
     product.StoresStockedIn.Add(this); 
     Products.Add(product); 
    } 

    public virtual void AddEmployee(Employee employee) 
    { 
     employee.Store = this; 
     Staff.Add(employee); 
    } 
} 

查詢數據我做的如下:

public IEnumerable<Product> QueryAllProducts(long? asOf) 
    { 
     using (var session = SessionFactory.OpenSession()) 
     { 
      session.EnableFilter(VersionFilter.Name).SetParameter(VersionFilter.Parameter, asOf); 
      return session.QueryOver<Product>().List<Product>(); 
     } 
    } 

在NHibernate調試日誌中,我看到以下內容。當我構造SessionFactory時。我看到下面的錯誤,那我不知道如何解釋:

2015-04-30 13:53:32,398 [1] ERROR NHibernate.Cfg.Configuration - filter-def for filter named 'VersionedDataModel1.VersionFilter, VersionedDataModel1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' was never used to filter classes nor collections. This may result in unexpected behavior during queries

而且在日誌中我沒有看到參考過濾器和沒有我的產品收集過濾。可能是我錯過了這個概念。

我的想法是爲整個會話應用此過濾器(VersionFilter),以便使用被查詢都會有這樣的addidional WHERE ...條件的所有實體。

因此是一個問題 - 我在Filter/FilterDefinition中丟失了什麼?

謝謝!

回答

1

您已經將過濾器註冊到nhibernate,現在您必須在您的映射類或集合中調用引用。

我從來沒有通過屬性用來映射,但我asume你需要使用NHibernate.Mapping.Attributes.Filter與實體(類級別)涉及過濾

或動態如下:

var filterParametersType = new Dictionary<string, Itype>(1); 
filterParametersType.Add("current", NhibernateUtil.Enum(typeof(ContextType))); 
cfg.AddFilterDefinition(new FilterDefinition("contextFilter", ":current = Context", filterParametersType)); 

foreach (var mapping in cfg.ClassMappings) 
{ 
    if (typeof(IContextAware).IsAssignableFrom(mapping.MappedClass)) 
    { 
     mapping.AddFilter("contextFilter", ":current = Context"); 
    } 
} 

你可以閱讀更多here在nhibernate文檔中。