2

データベースから記録された ELMAH 例外を取得する簡単なコードがあります。

HealthMonitoringEntities context = new HealthMonitoringEntities();
IQueryable<ELMAH_Error> exceptions = context.ELMAH_Error;

if (filter.ToDate != null)
    exceptions = exceptions.Where(e => e.TimeUtc <= filter.ToDate.Value.AddHours(-4));

return exceptions.OrderByDescending(e => e.TimeUtc)
    .Take(filter.Size)
    .AsEnumerable()
    .Select(e => new ElmahException()
    {
        ErrorId = e.ErrorId,
        Application = e.Application,
        Host = e.Host,
        Type = e.Type,
        Source = e.Source,
        Error = e.Message,
        User = e.User,
        Code = e.StatusCode,
        TimeStamp = e.TimeUtc.AddHours(-4).ToString()
    }).ToList();

    }

この行で例外が発生します。

  TimeStamp = e.TimeUtc.AddHours(-4).ToString()

例外は次のとおりです。

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

.AsEnumerable()で投影する前に を呼び出すとSelect()、シーケンスが列挙され、 を実装するシーケンスから投影されIEnumerable<ELMAH_Error>ます。AddHours()それを考えると、Linq-To-Entities API を引き続き使用するのではなく、なぜ を理解する投影で Linq-To-Objects API を使用しないのですか?

アップデート

Jon Skeet によるこのトピックに関する投稿がここにあります。

http://msmvps.com/blogs/jon_skeet/archive/2011/01/14/reimplementing-linq-to-objects-part-36-asenumerable.aspx

彼はこのクエリを持っています:

var query = db.Context 
          .Customers 
          .Where(c => some filter for SQL) 
          .OrderBy(c => some ordering for SQL) 
          .Select(c => some projection for SQL) 
          .AsEnumerable() // Switch to "in-process" for rest of query 
          .Where(c => some extra LINQ to Objects filtering) 
          .Select(c => some extra LINQ to Objects projection);

への電話の後、AsEnumerable()彼は Linq-To-Objects に切り替えることを示したことに注意してください。関数で同様のことを行っていますが、Linq-To-Objects API に対して実行すると思っていた場所で、Linq-To-Entities 例外を受け取っています。

更なるアップデート

Jim Wooley のブログから: http://linqinaction.net/blogs/jwooley/archive/2009/01/21/linq-supported-data-types-and-functions.aspx

「例として、次のメソッドは、DateTime 値の変換を持つものとして示されています: Add、Equals、CompareTo、Date、Day、Month、Year。対照的に、ToShortDateString、IsLeapYear、ToUniversalTime などのメソッドはサポートされていません。

サポートされていないメソッドのいずれかを使用する必要がある場合は、結果をクライアントに強制し、その時点で LINQ to Objects を使用して結果を評価する必要があります。クエリ内包表記の任意の時点で .AsEnumerable 拡張メソッドを使用してそれを行うことができます。」

それは私がしていることではありませんか?

4

1 に答える 1