データベースから記録された 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 によるこのトピックに関する投稿がここにあります。
彼はこのクエリを持っています:
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 拡張メソッドを使用してそれを行うことができます。」
それは私がしていることではありませんか?