WEB开发网
开发学院软件开发C语言 趣味编程:C#中Specification模式的实现(参考答案... 阅读

趣味编程:C#中Specification模式的实现(参考答案 - 下)

 2010-09-30 21:01:37 来源:WEB开发网   
核心提示: 于是,我们最终构造得到的Expression<Func<T, bool>>对象便可以传入一个LINQ Provider,趣味编程:C#中Specification模式的实现(参考答案 - 下)(4),最终得到查询结果:Expression<Func<int,b

于是,我们最终构造得到的Expression<Func<T, bool>>对象便可以传入一个LINQ Provider,最终得到查询结果:

Expression<Func<int, bool>> f = i => i % 2 == 0; 
f = f.Not().And(i => i % 3 == 0).Or(i => i % 4 == 0); 
 
foreach (var i in new int[] { 1, 2, 3, 4, 5, 6 }.AsQueryable().Where(f)) 
{ 
  Console.WriteLine(i); 
} 

输出的结果是3和4。

这种做法是非常有实用价值的。因为有了LINQ,因此许多朋友都会选择在数据访问层暴露一个这样的方法给上层调用:

class ProductDao 
{ 
  public Product GetProduct(Expression<Func<Product, bool>> predicate) 
  { 
    ... 
  } 
} 

但是您有没有想过这么做的缺点是什么呢?这么做的缺点便是“过于自由”。由于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模式中复杂的实现,您是否会有一种满足感?

文章来源:http://www.cnblogs.com/JeffreyZhao/archive/2009/09/29/specification-pattern-in-csharp-practice-answer-2.html

上一页  1 2 3 4 

Tags:趣味 编程 Specification

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接