如何重构多个类似的Linq-To-Sql查询?(How to refactor multiple similar Linq-To-Sql queries?)

在downvoting或关闭之前读取: 我之前几个问题的几乎完全相同的副本存在,其目的只是将上一个问题改写为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参数作为参数传递?

当我尝试枚举结果时,在上一个问题中发布的所有解决方案都已经过尝试并且在运行时失败。

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

Read before downvoting or closing: This almost exact duplicate of a previous question of mine exists with the solely purpose to rephrase the previous question to the Linq-To-Sql scope. All answers contained in the previous question are valid for the Linq scope, but are invalid in the Linq-To-SQL scope.

Suppose I have the two following Linq-To-SQL queries I want to refactor:

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 );

Note that only the Where parameter changes. There is any way to put the query inside a method and pass the Where parameter as an argument?

All the solutions posted in the previous question have been tried and failed in runtime when I try to enumerate the result.

The exception thrown was: "Unsupported overload used for query operator 'Where'"

最满意答案

绝对。 你写的:

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

(这是假设TableA是IQueryable<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 。

Absolutely. You'd write:

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

(That's assuming that TableA is IQueryable<A>.)

Call it with:

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

I believe that will work...

The difference between this and the answers to your previous question is basically that this method takes Expression<Func<T,bool>> instead of just Func<T,bool> so it ends up using Queryable.Where instead of Enumerable.Where.

更多推荐