Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在参数化表达式中排除子句?_C#_Linq_Entity Framework_Linq To Entities_Expression Trees - Fatal编程技术网

C# 如何在参数化表达式中排除子句?

C# 如何在参数化表达式中排除子句?,c#,linq,entity-framework,linq-to-entities,expression-trees,C#,Linq,Entity Framework,Linq To Entities,Expression Trees,大家好。我试图通过静态缓存和重用已编译的查询来优化LINQtoEntities调用。查询会检查相同的内容以获得数量可变的筛选器参数,而编译此类查询参数的唯一方法是显式使用大量参数(而不是一些包含()类型逻辑,在SQL中无法参数化) 这工作得很好,给了我很大的性能提升。问题是代码很难看。我对每个可能的参数重复相同的代码块多次。即: Expression<Func<Entities, string, string, string, string, IQueryabl

大家好。我试图通过静态缓存和重用已编译的查询来优化LINQtoEntities调用。查询会检查相同的内容以获得数量可变的筛选器参数,而编译此类查询参数的唯一方法是显式使用大量参数(而不是一些包含()类型逻辑,在SQL中无法参数化)

这工作得很好,给了我很大的性能提升。问题是代码很难看。我对每个可能的参数重复相同的代码块多次。即:

           Expression<Func<Entities, string, string, string, string, IQueryable<Instrument>>> query = 
(context, searchTerm0, searchTerm1, searchTerm2, searchTerm3) =>
                context.Instruments
                    .Where(
                        (searchTerm0 == null ||
                            instr.FullName.IndexOf(searchTerm0) > -1 ||
                            instr.ShortName.IndexOf(searchTerm0) > -1 ||
                            instr.Strategies.OrderBy(st => st.Level).Select(st => st.Name).Take(2).Any(strat => strat.IndexOf(searchTerm0) > -1))
                        &&
                        (searchTerm1 == null ||
                            instr.FullName.IndexOf(searchTerm1) > -1 ||
                            instr.ShortName.IndexOf(searchTerm1) > -1 ||
                            instr.Strategies.OrderBy(st => st.Level).Select(st => st.Name).Take(2).Any(strat => strat.IndexOf(searchTerm1) > -1))
                        &&
                        (searchTerm2 == null ||
                            instr.FullName.IndexOf(searchTerm2) > -1 ||
                            instr.ShortName.IndexOf(searchTerm2) > -1 ||
                            instr.Strategies.OrderBy(st => st.Level).Select(st => st.Name).Take(2).Any(strat => strat.IndexOf(searchTerm2) > -1))
                        &&
                        (searchTerm3 == null ||
                            instr.FullName.IndexOf(searchTerm3) > -1 ||
                            instr.ShortName.IndexOf(searchTerm3) > -1 ||
                            instr.Strategies.OrderBy(st => st.Level).Select(st => st.Name).Take(2).Any(strat => strat.IndexOf(searchTerm3) > -1))
                .Take(50);
表达式查询=
(上下文、搜索术语0、搜索术语1、搜索术语2、搜索术语3)=>
背景.文书
.在哪里(
(searchTerm0==null||
instr.FullName.IndexOf(searchTerm0)>-1||
instr.ShortName.IndexOf(searchTerm0)>-1||
instr.Strategies.OrderBy(st=>st.Level).选择(st=>st.Name).取(2).Any(strat=>strat.IndexOf(searchTerm0)>-1))
&&
(searchTerm1==null||
仪器全名索引(搜索术语1)>-1||
instr.ShortName.IndexOf(searchTerm1)>-1||
instr.Strategies.OrderBy(st=>st.Level).选择(st=>st.Name).取(2).Any(strat=>strat.IndexOf(searchTerm1)>-1))
&&
(searchTerm2==null||
仪器全名索引(搜索术语2)>-1||
instr.ShortName.IndexOf(searchTerm2)>-1||
instr.Strategies.OrderBy(st=>st.Level).选择(st=>st.Name).取(2).Any(strat=>strat.IndexOf(searchTerm2)>-1))
&&
(searchTerm3==null||
仪器全名索引(搜索术语3)>-1||
instr.ShortName.IndexOf(搜索术语3)>-1||
instr.Strategies.OrderBy(st=>st.Level).选择(st=>st.Name).取(2).任意(strat=>strat.IndexOf(searchTerm3)>-1))
.采取(50);
我以为我可以通过动态创建过滤器表达式来重构它,但这似乎是不可能的。我想这样做:

    var filterExpression = (instr, searchTerm) =>
        searchTerm == null ||
        instr.FullName.IndexOf(searchTerm) > -1 ||
        instr.ShortName.IndexOf(searchTerm) > -1 ||
        instr.Strategies.OrderBy(st => st.Level).Select(st => st.Name).Take(2).Any(strat => strat.IndexOf(searchTerm) > -1);

    Expression<Func<Entities, string, string, string, string, IQueryable<Instrument>>> query = (context, searchTerm0, searchTerm1, searchTerm2, searchTerm3) =>
        context.Instruments
            .Where(i => filterExpression(i, searchTerm0))
            .Where(i => filterExpression(i, searchTerm1))
            .Where(i => filterExpression(i, searchTerm2))
            .Where(i => filterExpression(i, searchTerm3))
        .Take(50);
var filtereexpression=(instr,searchTerm)=>
searchTerm==null||
instr.FullName.IndexOf(searchTerm)>-1||
instr.ShortName.IndexOf(搜索术语)>-1||
instr.Strategies.OrderBy(st=>st.Level).选择(st=>st.Name).取(2).Any(strat=>strat.IndexOf(searchTerm)>-1);
表达式查询=(上下文、searchTerm0、searchTerm1、searchTerm2、searchTerm3)=>
背景.文书
.其中(i=>filterExpression(i,searchTerm0))
.其中(i=>filterExpression(i,searchTerm1))
.其中(i=>filterExpression(i,searchTerm2))
.其中(i=>filterExpression(i,searchTerm3))
.采取(50);
但当然,这不会编译,因为filterExpression是一个表达式,不能像那样被调用(它不能只是一个Func,因为Linq to Entities不会将其识别为可翻译方法)

我也不能在表达式外部捕获闭包中的参数,因为如果我重用编译后的表达式,最后一次调用的值将被硬编码并重新使用。也就是说,这不是一个参数化查询

每个学期我都要写完整的内容吗?我想最多支持14个。有没有可能用这种方式计算出包含参数的子句?

请检查。文档非常好

我已经用它来支持几十个谓词,经过良好的分解,生成的代码很小。

请查看。文档非常好


我用它来支持几十个谓词,经过良好的分解,生成的代码很小。

不确定谓词生成器将如何帮助我。我想做的是创建一个表达式并编译一次,然后用不同的参数重新使用它。除非我遗漏了什么,否则谓词生成器示例使用捕获的筛选值在闭包中,也就是说,它们不是表达式的参数,将在编译后的查询的后续使用中重复使用。我明白了吗?啊…我明白你在寻找什么。你是对的,谓词生成器不会为你这样做。但是,我认为你不能在LINQ到EF中使用编译方法。本质上,所有的predicATE被转换为T-SQL。编译后的查询无法由LINQ转换为EF提供程序,最终您将求助于谓词生成器。是的,我在顶部采用的方法有效-我可以编译compete表达式并使用不同的参数成功重用它-但我最终不得不写出who支持多达12个参数是一件很糟糕的事情。我不确定谓词生成器将如何帮助我。我想做的是创建一个表达式并编译一次,然后使用不同的参数重新使用它。除非我遗漏了什么,否则谓词生成器示例使用闭包中捕获的筛选值,即它们不是Ex的参数按并将在编译后的查询的后续使用中重复使用。我明白了吗?啊…我明白你在寻找什么。你是对的,谓词生成器不会为你这样做。但是,我认为你不能在LINQ到EF中执行编译方法。本质上,所有谓词都转换为t-SQL。编译后的查询无法执行我不能被LINQ转换为EF提供者,你最终会求助于谓词生成器。是的,我在顶层的方法很有效-我可以编译compete表达式并使用不同的参数成功地重用它-但我最终不得不写出整个该死的东西来支持多达12个p