【问题标题】:Workaround for "LINQ to Entities does not recognize the method 'Int32 Parse(System.String)'“LINQ to Entities 无法识别方法 'Int32 Parse(System.String)' 的解决方法
【发布时间】:2011-12-07 10:57:33
【问题描述】:

我有一个如下所示的表格:

Foo
 FooId : int (PK)
 BarId : int
 Baz   : bit
 etc.

它还有其他列(等等),但我有一个特定的查询,我想运行它来预测一些统计信息。 SQL 中的查询如下所示:

SELECT 
 BarId, 
 SUM(CAST(Baz AS INT)) AS BazCount
 FROM Foo GROUP BY BarId;

所以,我创建了一个 Presentation Model 类来保存数据,这样我就可以将它返回给客户端。

public partial class FooStatistics
{
  public int BarId { get; set; }
  public int BazCount { get; set; }
}

我不是 100% 确定如何在 LINQ 中执行相同的查询并将其投影到这个对象中,但我试了一下:

FooStatistics stats = (
    from f in ctx.Foo
    where <clauses here>
    group f by f.BarId
      into StatsGroup
      select new FooStatistics() {
        BarId = StatsGroup.Key,
        BazCount = StatsGroup.Sum(f => Int32.Parse(f.Baz.ToString()))
      }
    ).FirstOrDefault();

这会导致错误:

LINQ to Entities 无法识别方法 'Int32 Parse(System.String)' 方法,并且该方法无法转换为存储表达式。

所以,我遵循了这里给出的建议:

LINQ to Entities does not recognize the method 'Double Parse(System.String)' method, and this method cannot be translated into a store expression

我将此添加到我的 .edmx XML 中

<Function Name="ParseInt" ReturnType="Edm.Int32">
  <Parameter Name="value" Type="Edm.String" />
  <DefiningExpression>
     cast(value as Edm.Int32)
  </DefiningExpression>
</Function>

然后我添加了一个分部类来定义方法:

public partial class MyEntities
{
   [EdmFunction("MyEntities", "ParseInt")]
   public static Int32 ParseInt(string value)
   {
       return Int32.Parse(value);
   }
}

我将 LINQ 更改为:

FooStatistics stats = (
    from f in ctx.Foo
    where <clauses here>
    group f by f.BarId
      into StatsGroup
      select new FooStatistics() {
        BarId = StatsGroup.Key,
        BazCount = StatsGroup.Sum(f => MyEntities.ParseInt(f.Baz.ToString()))
      }
    ).FirstOrDefault();

但这会导致:

LINQ to Entities 无法识别方法 'System.String ToString()' 方法,并且该方法无法转换为存储表达式。

所以,我将 .edmx XML 中的函数更改为:

<Function Name="BoolToInt32" ReturnType="Edm.Int32">
   <Parameter Name="value" Type="Edm.Boolean" />
   <DefiningExpression>
      cast(value as Edm.Int32)
   </DefiningExpression>
</Function>

我相应地将我的静态 ParseInt 更改为 BoolToInt32 并且我更改了 LINQ 以使用该函数,但现在它爆炸了:

无法将指定的方法“Int32 BoolToInt32(Boolean)”转换为 LINQ to Entities 存储表达式。

我是接近了,还是我做错了...?

提前致谢

【问题讨论】:

    标签: c# linq entity-framework


    【解决方案1】:

    如果 Baz 有点,你可以添加一个 where 然后使用 Count() 如下

    FooStatistics stats = (
        from f in ctx.Foo
        where <clauses here>
           and f.Baz
        group f by f.BarId
          into StatsGroup
          select new FooStatistics() {
            BarId = StatsGroup.Key,
            BazCount = StatsGroup.Count()
          }
        ).FirstOrDefault();
    

    【讨论】:

    • 感谢@Steven,这非常有效——不知道为什么我忽略了 Count——这是漫长的一天 :)
    猜你喜欢
    • 2015-09-20
    • 2015-07-20
    • 1970-01-01
    • 2015-07-25
    • 1970-01-01
    • 2020-01-26
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    相关资源
    最近更新 更多