但是您有沒有想過這麼做的缺點是什麼呢?這麼做的缺點便是“過於自由”。由於GetProduct方法只將參數限制為一個 Expression<Func<Product, bool>>對象,因此在調用的時候,我們可以使用任意的形式進行傳遞。因此,外層完全有可能傳入一個目前LINQ Provider不支持的表達式樹形式,也完全有可能傳入一個雖然支持,但會導致查詢速度慢,影響項目整體性能的表達式樹。前者要在運行時才拋出異常,而後者則引發的性能問題則更難發現。因此我認為,數據訪問層不應該如此自由,它要做出限制。而限制的方式,便是使用Query Object模式,讓GetProduct方法接受一個受限的Criteria對象:
public abstract class ProductCriteria
{
internal ProductCriteria(Expression<Func<Product, bool>> query)
{
this.Query = query;
}
public Expression<Func<Product, bool>> Query { get; private set; }
}
class ProductDao
{
public Product GetProduct(ProductCriteria predicate)
{
...
}
}
而在使用時,我們只提供有限的幾種條件,如:
public class ProductIdEqCriteria : ProductCriteria
{
public ProductIdEqCriteria(int id)
: base(p => p.ProductID == id)
{ }
}
public class ProductVIEwRangeCriteria : ProductCriteria
{
public ProductVIEwRangeCriteria(int min, int max)
: base(p => p.ViewCount > min && p.VIEwCount < max)
{ }
}
再加上配套的擴展方法用於And,Or,Not,於是一切盡在掌握。現在再去瞅瞅原Query Object模式中復雜的實現,您是否會有一種滿足感?