我有一些简单的代码可以检索数据库中记录的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>的序列中进行项目。既然如此,为什么我在我的投影中不使用Linq到Objects API,因为它理解AddHours(),而不是仍然使用Linq到实体API?
更新
乔恩·斯基特在这里发表了一篇关于这一主题的文章:
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到对象。我在我的函数中做了类似的事情,但是我收到了一个Linq到实体的异常,在那里我以为我会针对执行。
进一步更新
来自Jim的博客: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对象来规避它们。您可以在查询理解的任何点使用.AsEnumerable扩展方法。“
这不是我在做的吗?
发布于 2013-11-07 13:43:07
你忘了保护你的第一个电话
if (filter.ToDate != null)
exceptions = exceptions.AsEnumerable()
.Where(e => e.TimeUtc <= filter.ToDate.Value.AddHours(-4));编辑记住,IQueryables在枚举之前不会被转换为IQueryables,所以您的调试器将执行该行,但在返回之前不会发生错误。如果filter.ToDate为null,则代码等效于以下内容:
if(filter.ToDate == null)
return exceptions
.Where(e => e.TimeUtc <= filter.ToDate
.Value
.AddHours(-4)) //uh-oh won't work in Linq-to-Entities
.OrderByDescending(e => e.TimeUtc)
.Take(filter.Size)
.AsEnumerable() //too late to protect you!
.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() //if we get this far we're OK
}).ToList();https://stackoverflow.com/questions/19836385
复制相似问题