2013-10-07 19 views
1

我一直無法獲得此通用nhibernate查詢,因​​爲我一直在獲取:Restrictions.On(_func) - 從範圍''引用'Product'類型的變量'p',但未在傳遞中定義

從範圍「」引用類型「產品」變的「p」,但它沒有定義

我已經有大量不同的答案對這個問題的左右撥弄,而且我認爲我瞭解問題所在,我只是不確定如何解決問題。據我所知,'p'存在於原始範圍中,但在到達nhibernate queryover命令時停止存在,因此,由於Linq通過名稱引用對象,實際上並不知道我在說什麼了。 。

我試過各種方法包括在: variable 'x' of type 'Product' referenced from scope, but it is not defined; NHibernate : QueryOver in generic method; Generic Repository with nHibernate; LambdaExpression Variable Referenced From Scope But Not Defined; LINQ expressions. Variable 'p' of type referenced from scope, but it is not defined

不幸的是,沒有一個提供了能夠解決問題的答案。查詢:

public class ProductsInformationQuery<T>: Query<T> where T:Product 
{ 
    private readonly List<string> _ids; 
    private readonly Expression<Func<T, object>> _func; 

    public ProductsInformationQuery(List<string> ids, 
     FeaturedIdType featureIdType, Expression<System.Func<T,object>> func) 
    { 
     _ids = ids; 
     _func = func; 
    } 

    public override List<T> Execute() 
    { 
     return Session.QueryOver<T>().Where(Restrictions.On<T>(_func).IsIn(_ids.Select(i => i).ToList())).List().ToList(); 
    } 
} 

這需要一個字符串列表並檢查數據庫中的特定查詢。這將允許我們嘗試並檢查數據庫中的一組ID; Ids可以是Guids(例如Id)或Strings(例如Name)。

調用代碼:

private List<Product> LoadProducts(List<string> ids) 
    { 
     System.Linq.Expressions.Expression<Func<Product, object>> function = b => b.Id.ToString(); 
     return _productsRepository.Execute(new ProductsInformationQuery<Product>(ids, FeaturedIdType.ProductId,function)).ToList(); 
    } 

此代碼需要能夠發送「B => b.Id.ToString()」作爲它需要檢查的功能。 QueryOver命令將需要通過其Id來查找產品。產品是繼承鏈的頂層,所以我希望能夠通過數據庫中的各種類型的信息找到各種類型的產品。

有趣的是我能得到以下工作:

return Session.QueryOver<T>().Where(Restrictions.On<T>(b=>b.Id).IsIn(_ids.Select(Guid.Parse).ToList())).List().ToList(); 

但並不是有以下兩種:

return Session.QueryOver<T>().Where(Restrictions.On<T>(b=>b.Id).IsIn(_ids)).List().ToList(); 

((AOD除外))

return Session.QueryOver<T>().Where(Restrictions.On<T>(b=>b.Id.ToString()).IsIn(_ids)).List().ToList(); 

((上述錯誤;「變量'b'類型...」))

前者是Guid to Guid的比較,第二個是Guid to String(並不意外Guid to string與nhibernate不起作用),第三個是Guid into String to string,這會改變b而不是僅僅收集數據。

有沒有什麼辦法讓它取得字符串和Guids和整數以及其他數據類型,同時還能夠接受任何類型的產品?或者我僅限於製作多個版本的查詢?

謝謝!

回答

0

我會爲您的類添加一個泛型類型參數TIdType,該類代表您要使用的標識的類型。這最終會看起來像這樣:

public class ProductsInformationQuery<TResultType, TIdType>: Query<TResultType> 
    where TResultType : Product 
{ 
    private readonly List<TIdType> _ids; 
    private readonly Expression<Func<TResultType, object>> _func; 

    public ProductsInformationQuery(
     List<TIdType> ids, 
     FeaturedIdType featureIdType, 
     Expression<System.Func<TResultType, TIdType>> func) 
    { 
     _ids = ids; 

     System.Linq.Expressions.Expression converted = 
      System.Linq.Expressions.Expression.Convert(func.Body, typeof(object)); 

     _func = System.Linq.Expressions.Expression.Lambda<Func<TResultType, object>> 
      (converted, func.Parameters); 
    } 

    public override List<TResultType> Execute() 
    { 
     return Session.QueryOver<TResultType>() 
      .Where(Restrictions.On<TResultType>(_func) 
       .IsIn(_ids.ToArray()) 
      .List() 
      .ToList(); 
    } 
} 

我把代碼給Expression<Func<TResultType, TIdType>>this answer轉換爲Expression<Func<TResultType, object>>

調用代碼是這樣的:

private List<Product> LoadProducts(List<string> ids) 
{ 
    System.Linq.Expressions.Expression<Func<Product, Guid>> function = b => b.Id; 
    return _productsRepository.Execute(
     new ProductsInformationQuery<Product, Guid> 
      (ids, FeaturedIdType.ProductId, function)) 
     .ToList(); 
} 
相關問題