Linq:让声明为常数?

时间:2017-06-14 17:57:55

标签: c# .net linq entity-framework-6 expression-trees

我正在研究Linq查询表达式语句,并希望使用 let 语句将常量值设置为查询的一部分以减少潜在错误。

在我的例子中......(这是完全模拟)。 let语句“validateCount”就是问题。

webRequest

不幸的是,似乎let表达式“validateCount”在此示例中具有单个值8,只能在.Count()的比较部分中工作,但不能在不抛出异常的情况下传递给.Take()

限制必须是DbConstantExpression或DbParameterReferenceExpression。 参数名称:count

寻找一种解决方案,在单个代码位置使用一些用户定义的常量,可以在.Take()和.Count()的其余部分中使用,而不必更新几个位置在代码中。

我们的应用程序允许用户提供自己的linq查询表达式来构建他们的查询。我无法定义此查询范围之外的任何内容,并且必须使用类似'let'语句的内容。

1 个答案:

答案 0 :(得分:2)

let语句在查询表达式树中生成中间匿名类型投影(Select调用)。 EF查询提供程序(由异常消息指示)需要将SkipTake参数解析为常量或变量值(即能够在本地进行求值),因此let不能用于此目的。

相反,Skip / Take表达式中使用的常量/变量应该在查询之外定义并在内部使用。

要定义您将使用的常量值:

const int validateCount = 8;
var query = (from .... Take(validateCount) ...);

定义变量值(SQL查询参数):

int validateCount = 8;
var query = (from .... Take(validateCount) ...);

这里C#编译器会将validateCount变为闭包,EF查询提供程序将很乐意绑定一个参数(带有该值)。

  

我们的应用程序允许用户提供自己的linq查询表达式来构建他们的查询。我无法定义此查询范围之外的任何内容,并且必须在其中,使用类似于' let'言。

在提供自己的查询时,用户应遵循与上述相同的Skip / Take参数规则,即在查询之外定义其常量和变量。