And*_*way 12 .net c# linq entity-framework entity-framework-5
我有一些代码最近从EF 4.2升级到EF 5.0(实际上是EF 4.4,因为我在.Net 4.0上运行).我发现我必须改变查询的语法,我很好奇为什么.让我从问题开始吧.
我有一个EventLog表,由客户端定期填充.对于每个事件日志,将在"报告"表中创建一个条目.这是定期运行的查询,用于发现尚未在"报告"表中包含条目的任何事件日志.我在EF 4.2中使用的查询是:
from el in _repository.EventLogs
where !_repository.Reports.Any(p => p.EventLogID == el.EventlogID)
从升级到EF 5.0后,我在运行时收到以下错误:
System.NotSupportedException:无法创建"Namespace.Report"类型的常量值.在此上下文中仅支持基元类型或枚举类型.
我发现使用join语法重写它可以解决问题.以下适用于EF 5.0,大致相当于:
from eventLog in _repository.EventLogs
join report in _repository.Reports on eventLog.EventlogID equals report.EventLogID into alreadyReported
where !alreadyReported.Any()
有些人可能对第一个查询的混合语法/样式有不同的看法,但我真的对这个原因更感兴趣.看起来奇怪的是EF 4.2编译器可以为原始查询生成SQL但是EF 5.0拒绝了.这是我缺少的设置还是两者之间的约束?为什么会这样?
该问题是由您的存储库返回的类型引起的;_repository.Reports当不是时,问题可以重现IQueryable<T>。在这种情况下,Reports被视为非标量变量;顺便说一句,这在 LINQ 中是不允许的。请参阅引用不支持的非标量变量
关于您关于为什么第二个查询有效的问题,它基本上是哪个IQueryable<T>组将其与IEnumerable<TInner>.
public static IQueryable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
    this IQueryable<TOuter> outer,IEnumerable<TInner> inner,
    Expression<Func<TOuter, TKey>> outerKeySelector,
    Expression<Func<TInner, TKey>> innerKeySelector,
    Expression<Func<TOuter, IEnumerable<TInner>, TResult>> resultSelector)
它只接受外部和内部的关键选择器的表达式(而不是引用非标量变量);其中上述约束不适用。
注意:如果_repository.Reports是IQueryable<T>第一个查询就可以;因为EF会正确构建表达式树并执行适当的SQL。
| 归档时间: | 
 | 
| 查看次数: | 549 次 | 
| 最近记录: |