2009-10-23 125 views
3

我需要使用SQRT函数作为Linq EF查询中where子句的一部分。我想我可以做到这一点。在Linq EF查询中使用SQRT

var qry = context.MyTable.Where("sqrt(it.field) > 1"); 

但它返回一个错误说“‘开方’不能被解析成一个有效的类型构造函数或函数,近函数,方法或类构造函数,第6行,第5栏。 “

我一直认为linq从字面上理解where子句中的内容,并将其转换为直接在SQL中执行的语句。这似乎并不是这样的...

任何人都知道解决方法吗?

感谢

+0

我假设你需要比较的数字不总是一个,对吧?原因...如果是...只是不使用sqrt。 Sqrt(1)= 1 – PeterAllenWebb 2009-10-24 04:45:15

+0

Retag。没有C#3.5(请参阅http://stackoverflow.com/questions/247621/what-are-the-correct-version-numbers-for-c) – Vaccano 2009-11-02 23:14:00

回答

2

我使用LINQ实体,是能够做到这一点:

 testEntities entities = new testEntities(); 

     ObjectQuery<Fees> fees = entities.Fees; 

     return from f in fees 
       let s = Math.Sqrt((double)f.FeeAmount) 
       where s > 1.0 
       select f ; 

当我检查生成的SQL,我得到

SELECT [t1].[TestTriggerID] 
FROM (
    SELECT [t0].[TestTriggerID], SQRT(CONVERT(Float,[t0].[TestTriggerID])) AS [value] 
    FROM [TestTrigger2] AS [t0] 
    ) AS [t1] 
WHERE [t1].[value] > @p0 

这似乎是合理的。我无法使用.Where字符串格式来重现相同的代码,但我可能错过了一些明显的东西。

+0

我做过类似的尝试,除了我使用Math.Sqrt没有赋值的选择部分。做一些项目是为了让他们在本地工作而不是在某个地方工作? – bugfixr 2009-10-27 14:54:40

+0

LINQ查询实际上按照它们构建的顺序进行操作。 FROM定义源,LET用计算值增加。 WHERE子句现在具有它需要的项目(通过FROM + let构造的子查询)进行筛选,最后SELECT将值作为结果提供。将计算放入SELECT中对于WHERE子句的操作来说“太晚了”,而没有明确地将该结果用作子查询)。 – Godeke 2009-10-27 15:30:33

+1

嗯。当我写一些类似于你在这里使用的东西时,我得到一个NotSupportedException,'LINQ to Entities不能识别'Double Sqrt(Double)'方法,并且这个方法不能被转换成存储表达式。你使用EF4吗? – 2010-11-07 21:07:02

8

我不知道你是如何得到你的答案对EF工作。当我用EF4试用它时,它不适合我。我会得到:

LINQ to Entities无法识别方法'双Sqrt(双)​​'方法,并且此方法不能转换为存储表达式。

所以敲我的头这一段时间后(毕竟,Math.Pow(double)支持,并SQRT是在SQL中使用),我意识到价值的平方根是一样的半功率。

所以,这个解决方案工作正常。

from e in context.MyEntities 
    let s = Math.Pow(e.MyDouble, 0.5) 
    select s; 

生成的SQL使用POWER而不是SQRT

SELECT 
POWER(CAST([Extent1].[MyDouble] AS float), cast(0.5 as float(53))) AS [C1] 
FROM [dbo].[MyEntities] AS [Extent1] 

一个很简单的解决方法,以一个愚蠢的问题。希望这可以帮助别人。

+0

这是针对EF构建的:您可以从我的代码中看到我们使用的是ObjectQuery,这是一个实体框架概念。然而,由于我的答案是从2009年10月开始,实体框架4在2010年4月推出,我很确定它不是EF4解决方案。我很惊讶,如简单的查询会阻止EF4。 – Godeke 2010-11-08 21:33:16

+0

@Godeke。关于日期已经足够了。但是,这是令人惊讶的。不过,至少有一个解决方法。 – 2010-11-09 00:50:09

0

从EF6开始,您可以使用System.Data.Entity.SqlServer.SqlFunctions.SquareRoot