如何重构多个类似的Linq-To-Sql查询?

时间:2009-05-14 19:51:06

标签: c# .net linq-to-sql refactoring

在downvoting或关闭之前阅读:这个几乎完全相同的previous question of mine副本存在,其唯一目的是将上一个问题重新改写为Linq-To-Sql范围。上一个问题中包含的所有答案都对Linq范围有效,但在Linq-To-SQL范围内无效。

假设我想要重构以下两个Linq-To-SQL查询:

var someValue1 = 0;
var someValue2= 0;
var query1 = db.TableAs.Where( a => a.TableBs.Count() > someValue1 )
              .Take( 10 );
var query2 = db.TableAs.Where( a => a.TableBs.First().item1 == someValue2)
              .Take( 10 );

请注意,只有Where参数更改。有什么方法可以将查询放在方法中并将Where参数作为参数传递?

当我尝试枚举结果时,previous question中发布的所有解决方案都已在运行时尝试过并失败。

引发的异常是:“用于查询运算符的不支持的重载'Where'”

2 个答案:

答案 0 :(得分:6)

绝对。你写的是:

public IQueryable<A> First10(Expression<Func<A,bool>> predicate)
{
    return db.TableAs.Where(predicate).Take(10);
}

(假设TableAIQueryable<A>。)

用以下方式调用:

var someValue1 = 0;
var someValue2= 0;
var query1 = First10(a => a.TableBs.Count() > someValue1);
var query2 = First10(a => a.TableBs.First().item1 == someValue2);

相信会起作用......

此问题与上一个问题的答案之间的差异基本上是此方法仅使用Expression<Func<T,bool>>而不是Func<T,bool>,因此最终使用Queryable.Where代替Enumerable.Where

答案 1 :(得分:1)

如果您真的想要可重用性,可以尝试编写自己的运算符。例如。而不是反复写作:

var query = 
Products
    .Where(p => p.Description.Contains(description))
    .Where(p => p.Discontinued == discontinued);

你可以编写简单的方法:

public static IEnumerable<Product> ByName(this IEnumerable<Product> products, string description)
{
    return products.Where(p => p.Description.Contains(description));
}


public static IEnumerable<Product> AreDiscontinued(IEnumerable<Product> products, bool isDiscontinued)
{
    return products.Where(p => p.Discontinued == discontinued);
}

然后像这样使用它:

var query = Products.ByName("widget").AreDiscontinued(false);