0

我是第一次使用 LINQ to Entities。

我的数据存储有一个字符串字段,取决于某些其他字段,它通常是一个整数。我无法更改此数据库的结构。

EF 中有问题的表是 masterdatas。

我正在尝试根据基于 varname 字段的分组为 varvalue 字段中的这些记录创建总和,如下所示:

var varsum = from md in context.masterdatas
             where md.imparcid == SelectedDataSet.imparcid && md.varname == t.VarName
             group md by md.varname into g
             select new { varname = g.Key, SummedAmt = g.Sum(md => Convert.ToDouble(md.varvalue)) };

我收到错误 LINQ to Entities 无法识别方法 Double ToDouble(系统字符串)。

基于这个SO question,我在我的 EDMX 模型中添加了一个 DefiningExpression,并在我的数据模型的部分类中定义了该函数并使用了以下代码:

var varsum = from md in context.masterdatas
             where md.imparcid == SelectedDataSet.imparcid && md.varname == t.VarName
             group md by md.varname into g
             select new { varname = g.Key, SummedAmt = g.Sum(md => context.ParseDouble(md.varvalue)) };

现在我收到一个错误,即 ParseDouble 函数无法转换为 LINQ 到实体存储表达式。

我真正想做的就是让这个 SQL 语句运行:

SELECT [varname]
      ,[vartype]
      ,Sum(CASE WHEN Isnumeric([varvalue])=1 THEN cast([varvalue] as float) Else 0 END)
  FROM [masterdata]
  Group by varname, imparcid, vartype
  Having imparcid=25 AND varname = 'S2CMT8B'

我不知道完成这项工作的最佳方法。

4

1 回答 1

2

在您的 LINQ 查询的最后一行,您需要调用上下文类的静态 方法,而不是实例:ParseDoublecontext

// ...
select new { varname = g.Key, SummedAmt = g.Sum(md =>
    MyContextClass.ParseDouble(md.varvalue)) };
//  ^^^^^^^^^^^^^^
//  NOT the context instance, just the class name because ParseDouble is static

我相信只有在这种情况下,该EdmFunction属性才由 EF 处理,否则它会尝试调用该方法,就像引发异常的普通 .NET 方法一样。

编辑

EdmFunction属性中指定正确的模型命名空间也很重要。如果您的 EDMX 看起来像这样...

<edmx:ConceptualModels>
  <Schema Namespace="MyDBModel" Alias="Self"
      xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation"
      xmlns="http://schemas.microsoft.com/ado/2008/09/edm">

    <!-- etc. -->

    <Function Name="ParseDouble" ReturnType="Edm.Double">
      <Parameter Name="stringvalue" Type="Edm.String" />
      <DefiningExpression>
        cast(stringvalue as Edm.Double)
      </DefiningExpression>
    </Function>

  </Schema>
</edmx:ConceptualModels>

...您必须将架构的命名空间指定MyDBModel为的第一个参数EdmFunctionAttribute

[EdmFunction("MyDBModel", "ParseDouble")]
public static double ParseDouble(string stringvalue)
{
    // ...
}

否则ParseDouble将被视为普通的 .NET 方法并导致无法将其转换为存储表达式的异常。

于 2012-09-10T16:12:39.037 回答