开发者

Workaround for "LINQ to Entities does not recognize the method 'Int32 Parse(System.String)'

开发者 https://www.devze.com 2023-04-13 02:49 出处:网络
I\'ve got a table that looks like this: Foo FooId : int (PK) BarId : int Baz: bit etc. It has other columns in it (etc.), but I have a specific query that I want to run that projects some stati

I've got a table that looks like this:

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

It has other columns in it (etc.), but I have a specific query that I want to run that projects some statistics. The query in SQL would look like this:

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

So, I created a Presentation Model class to hold the data, so I can return it to the client.

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

I'm not 100% sure how to do the same query in LINQ and project it into this object, but I gave it a shot like this:

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();

This blows up with the error:

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

So, I followed the advice given开发者_开发问答 here:

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

I added this to my .edmx XML

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

Then I added a partial class to define the method:

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

And I changed my LINQ to:

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();

But this blows up with:

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

So, I changed the function in the .edmx XML to this:

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

And I changed my static ParseInt to BoolToInt32 accordingly and I changed the LINQ to use that function, but now it blows up with:

The specified method 'Int32 BoolToInt32(Boolean)' cannot be translated into a LINQ to Entities store expression.

Am I close, or am I doing it totally wrong...?

Thanks in advance


If Baz is a bit, you could add a where and then just use Count() as below

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();
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号