C# 带内部变量的cλ,用于预计算

C# 带内部变量的cλ,用于预计算,c#,entity-framework,lambda,func,C#,Entity Framework,Lambda,Func,我有一个实体框架应用程序,其过滤lambda表达式如下所示: x=>x.Wherepn=>pn.Product.Evaluation.Anyee=>ee.EvaluationToDocuments.Anye2d=>e2d.Document.SpiderFailedCheckCount!=无效的 事实证明,这是非常缓慢的,相反的方式会快得多,即找到正确的文档评估,并通过评估选择他们的产品 所以我做了一个预计算: SpiderFailedCheckCountProductId=\u context.

我有一个实体框架应用程序,其过滤lambda表达式如下所示:

x=>x.Wherepn=>pn.Product.Evaluation.Anyee=>ee.EvaluationToDocuments.Anye2d=>e2d.Document.SpiderFailedCheckCount!=无效的 事实证明,这是非常缓慢的,相反的方式会快得多,即找到正确的文档评估,并通过评估选择他们的产品

所以我做了一个预计算: SpiderFailedCheckCountProductId=\u context.EvaluationToDocuments.Wheree2d=>e2d.Document.SpiderFailedCheckCount!=null.Selecte2d=>e2d.Evaluation.ProductID.Distinct.OrderByp=>p.ToList

然后我的第一个表达式可以这样做: x=>x.Wherepn=>spiderfailedCheckCountProductId.Containspn.ProductID

它可能会更快,但这已经足够快了,比第一个版本快了很多数量级

一般来说,函数中使用局部变量的目的是避免多次进行昂贵的计算。这可以在lambda表达式中完成吗?比如x=>var a=x+5,a*4不是最好的例子

我希望避免编写普通函数,并将这些过滤函数保留为对象。

MSDN中有一个示例:

var earlyBirdQuery =
    from sentence in strings
    let words = sentence.Split(' ')
    from word in words
    let w = word.ToLower()
    where w[0] == 'a' || w[0] == 'e'
        || w[0] == 'i' || w[0] == 'o'
        || w[0] == 'u'
    select word;
但是请注意,您的问题是另一个:由您的查询生成的SQL查询计划非常糟糕。您通过对SQL执行两个单独的查询来解决此问题。。也许您甚至可以将这两个查询合并在一起,并在单个批中执行它们

SQL Server通常已经缓存了相等的子表达式。如果在查询中执行两次MAXsomething,SQL可能不会执行两次。它将注意到它可以重用结果并重用它

SELECT MAX(id), MAX(id) FROM Foo
或者如果你这样做了

SELECT SUBSTRING(name, 1, 5) FROM Foo WHERE SUBSTRING(name, 1, 5) = 'Hello'

可能每行只构建一次子字符串。

在这种情况下,SQL Server似乎没有捕捉到相等的子表达式。你有没有更好的方法来写我的lambda表达式的建议?我设法把它改成一个多行表达式,类似于你的let子句,但可以说它仍然是一个两级火箭。