2011-04-27 95 views
3

是否有可能将Subsonic 2.1中的多个过滤器组合到一段较短的代码中?结合多个SubSonic.Where过滤器

SubSonic.Where filterTaal = new SubSonic.Where(); 
     filterTaal.ColumnName = Pagina.Columns.Taal; 
     filterTaal.Comparison = SubSonic.Comparison.Equals; 
     filterTaal.ParameterValue = taal; 

    SubSonic.Where filterKey = new SubSonic.Where(); 
     filterKey.ColumnName = Pagina.Columns.PaginaKey; 
     filterKey.Comparison = SubSonic.Comparison.Equals; 
     filterKey.ParameterValue = paginaKey; 

     PaginaCollection paginaCollection = new PaginaCollection() 
      .Where(filterTaal) 
      .Where(filterKey) 
      .Load(); 

在我看来,上面的代码可以缩短?

回答

4

你可以编写自己的扩展方法和使用ExpressionTrees。 结果会是这样的:

PaginaCollection paginaCollection = new PaginaCollection() 
    .SlimWhere(x => x[paginaColumns.PaginaKey] == paginaKey) 
    .SlimWhere(x => x[paginaColumns.Taal] == taal) 
    .Load(); 

扩展方法将是不便。像这样:

public static PaginaCollector SlimWhere(this PaginaCollector paginaCollector, Expression<Func<WhereDummy, bool>> expression) 
{ 
    var mainExpression = expression.Body as BinaryExpression; 
    SubSonic.Where result = ParseFilter(mainExpression); 

    switch (mainExpression.NodeType) 
    { 
     case ExpressionType.Equal:   
      result.Comparison = Comparison.Equals; 
      break; 

     ... 

     default: 
      throw new NotImplementedException(); 
    } 

    return paginaCollector.Where(result); 
} 

和辅助方法是:

private static SubSonic.Where ParseFilter(BinaryExpression expression) 
{ 
    var columnNameMethod = (MethodCallExpression)expression.Left; 
    var columnNameExpression = columnNameMethod.Arguments[0]; 

    var parameterValueExpression = expression.Right; 

    string columnName = GetValue<string>(columnNameExpression); 
    object parameterValue = GetValue<object>(parameterValueExpression); 

    Where result = CreateWheteFilterDummy(columnName, parameterValue); 

    return result; 
} 

private static Where CreateWheteFilterDummy(string columnName, object parameterValue) 
{ 
    SubSonic.Where result = new Where(); 
    result.ColumnName = columnName; 
    result.ParameterValue = parameterValue; 
    return result; 
} 

private static T GetValue<T>(Expression columnNameExpression) 
{ 
    var columnNameObjectMember = Expression.Convert(columnNameExpression, typeof(T)); 
    var columnNameGetter = Expression.Lambda<Func<T>>(columnNameObjectMember); 
    return columnNameGetter.Compile()(); 
} 

WhereDummy是一个虚拟类只提供更可读的语法,因为.SlimWhere(paginaColumns.PaginaKey == paginaKey)不是这么理解的。

public class WhereDummy 
{ 
    public string this[string columnname] 
    { 
     get 
     { 
      return columnname; 
     } 
    } 
} 
+0

这是一个很好的答案,工程很酷;)。 – 2011-05-04 08:40:56