【发布时间】:2012-01-09 22:43:34
【问题描述】:
我刚刚遇到了一个非常令人惊讶的问题。
情况很简单:返回所有当前处于活动状态的实体,意思是:根据其布尔Active属性过滤GetAll()方法返回的所有结果
public IQueryable<T> GetAllActive()
{
return implementation.GetAll().Where(a => ((IDeactivable)a).Active);
}
其中GetAll()方法的实现对象定义为:
public IQueryable<T> GetAll();
问题是,GetAllActive() 返回所有记录,无论其 Active 属性的值如何,就像没有 Where 子句一样。
这可能是什么原因?
注意:代码简化,检查T类型实现IDeactivable接口。在运行时也不会抛出异常。
编辑:实现对象返回的IQueryable来自NHibernate
Edit2:我使用以下代码检查实体的实际值(除了使用 VS 调试器):
foreach (var a in active) { //active -> filtered IQueryable before return
_logger.Warn(a.Id);
_logger.Warn(((IDeactivable)a).Active);
}
结果是:
11/30/2011 18:10:00 WARN xxx.Repository`1.GetAllActive: 70db43fa-2361-4c1f-a8e5-9fab012b5a2b
11/30/2011 18:10:01 WARN xxx.Repository`1.GetAllActive: False
11/30/2011 18:10:02 WARN xxx.Repository`1.GetAllActive: 5493c9bb-ec6e-4690-b5d6-9fab012b5b16
11/30/2011 18:10:02 WARN xxx.Repository`1.GetAllActive: True
【问题讨论】:
-
要解决它,您必须证明
((IDeactivable)someRecord).Active实际上在应该返回false时返回。似乎它总是返回true。 -
你真的确定错误不喜欢你删除的一些代码吗?乍一看,它会做你想做的事。我的怀疑是问题出在您在简化中删除的代码中的某个地方,或者您是否证明上述代码确实也失败了?正如其他人可能会说的那样,您能否提供一个小而完整的程序来演示您的问题?
-
Where谓词中的任何内容都是相关的。不要简化这部分。 -
也用于调试尝试
implementation.GetAll().ToEnumerable().Where(...,它将在.net 中进行过滤而不是翻译它。 -
我已经尝试了几种写 Where 的方法,尽管它们中的大多数似乎都在做同样的工作,但结果是一样的。但是,我已经尝试了 CodeInChaos 提出的建议并且它确实有效。但它的真正原因是什么,它的作用是什么? QueryProvider 翻译器以某种方式忽略了我的过滤器?优化器?转换为 IEnumerable 并返回的性能开销是多少?
标签: c# .net nhibernate linq-to-nhibernate