动态构建LINQ查询-强制使用sp_executesql代替原始查询

时间:2018-07-06 10:11:37

标签: c# entity-framework linq expression

我需要动态构建查询(实体类具有30多个属性,我想避免使用多个if语句)。 我使用反射树和表达式树解决了这个问题(如果指定了某些搜索条件,则按属性进行迭代并附加谓词)。 问题在于它会生成原始SQL脚本。

示例

<template>
  <v-app>

  </v-app>
</template>

我需要使用 sp_executesql 过程(恢复相同的查询执行计划)来​​获取查询。

[Vue warn]: Unknown custom element: <v-app> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

found in

---> <App> at /var/www/project/resources/assets/App.vue
       <Root>

原来,问题出在下面的方法中。它使用Expression.Constant创建Expression对象。我不知道应该用什么代替。

SELECT 
    [Extent1].[ProductId] AS [ProductId], 
    [Extent1].[ManufacturerId] AS [ManufacturerId], 
    [Extent1].[Title] AS [Title]
    FROM [dbo].[Products] AS [Extent1]
    WHERE 3 = [Extent1].[ManufacturerId]

如何解决该问题?

1 个答案:

答案 0 :(得分:4)

为了让EF使用参数而不是常量值,您需要引入一个闭包(类似于C#编译器对编译时间表达式的处理)。

一种方法是创建匿名类型并绑定其属性:

var closure = new { value };
var body = Expression.Equal(Expression.Property(param, property),
    Expression.Property(Expression.Constant(closure), "value"));

另一种方法是实际使用C#编译器创建一个闭包表达式并绑定其主体:

Expression<Func<TValue>> closure = () => value;
var body = Expression.Equal(Expression.Property(param, property),
    closure.Body);