我正在尝试使用对象查询查询多个实体关系。
实体链基本上是OMRMARKET(一对多)属性(一对多)OMRBUILDINGSURVEYS(一对多)PERIODS。或者换句话说,市场有很多属性,属性有很多调查,调查有很多期间。
我想过滤以下对象查询:
OMRMarketsQuery = OMRMarketsQuery.Include("Properties.OMRBuildingSurveys")
关于期间ID(伪代码)OMRMarket.Properties.OMRBuildingSurveys.PeriodID> 50
然后我想我可能能够嵌套后续的Where函数,例如:
OMRMarketsQuery = OMRMarketsQuery.Include("Properties.OMRBuildingSurveys").Where(
Function(m) m.Properties.Where(Function(p) p.OMRBuildingSurveys.Where(Function(s)
s.PeriodID > 50)))
我获得intellisense支持,帮助我建立查询,但后来我得到了错误
类型'System.Collections.Generic.IEnumerable(Of OMR.OMRInterfaceCustomCode.OMRBuildingSurvey)'的值无法转换为'Boolean'
非常感谢任何帮助。我知道这一定是可行的。非常感谢提前。
答案 0 :(得分:0)
我们很难在不访问您的代码的情况下“调试”您的LinQ
。但是,当我编写复杂的LinQ
查询时,我总是尝试一次构建每个连续的步骤,这样如果我收到错误,我知道它来自我添加的最后一位。另外,请密切关注您正在调用的LinQ
方法所需的输入和返回类型。
作为示例,您的错误表明您的部分查询期望Boolean
类型而不是'System.Collections.Generic.IEnumerable(Of OMR.OMRInterfaceCustomCode.OMRBuildingSurvey)
类型...我唯一需要的Boolean
值在您的查询中查看来自Where
方法:
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)
因此,我只能假设您的部分查询返回了OMRBuildingSurvey
个对象的集合,而不是所需的Func<TSource, bool>
谓词。如果我们查看此部分p.OMRBuildingSurveys.Where(Function(s) s.PeriodID > 50)
,我们可以看到这将返回满足谓词条件的IEnumerable
个OMRBuildingSurvey
个实例。
但是,这个产生的集合正在被提供给m.Properties.Where
子句,它也期望Func<TSource, bool>
谓词...所以我们似乎找到了错误。
更新&gt;&gt;&gt;
好的...反对我更好的判断,我会给你一个机会,因为我对你班级的结构视而不见。
从右侧开始,我们已经p.OMRBuildingSurveys.Where(Function(s)
s.PeriodID > 50)
我们学会了返回满足谓词条件的IEnumerable
个OMRBuildingSurvey
个实例。那么这个系列的下一步是什么?
我们需要查找包含任何Property
个实例的OMRBuildingSurvey
个对象:
m.Properties.Where(Function(p) p.OMRBuildingSurveys.Intersect(p.OMRBuildingSurveys.
Where(Function(s) s.PeriodID > 50)).Any())
我甚至不确定这个是否会起作用...我们在这里尝试做的是返回包含项目的IEnumerable
类型Property
具有在OMRBuildingSurvey
(CLR)属性中满足PeriodID
谓词条件的任何OMRBuildingSurveys
个实例的任何实例。 Intersect
方法将每个OMRBuildingSurveys
属性的值与满足谓词条件的IEnumerable
个实例的OMRBuildingSurvey
的输出相连接,Any
返回任何该值是一样的。
最后一步将是这样的:
var query = OMRMarketsQuery.Include("Properties.OMRBuildingSurveys").Where(Function(m)
m.Properties.Intersect(m.Properties.Where(Function(p) p.OMRBuildingSurveys.
Intersect(p.OMRBuildingSurveys.Where(Function(s) s.PeriodID > 50)).Any())).Any())
我基本上做了同样的事情...使用前面的'查询到目前为止'作为Intersect
属性上调用的OMRBuildingSurvey.Properties
方法的输入参数。现在,我希望这是有效的,因为我没有更多的时间。此外,VB 可能
顺便说一句,此示例遵循问题中的要求,而不是最后的评论。
答案 1 :(得分:0)
好的答案很简单。
在使用“预先加载”或“延迟加载”时,您无法进行过滤。我自己和几个自由职业者尝试了各种方法,但答案是加载市场和属性,然后注释掉以下代码:
'OMRMarketsQuery = OMRMarketsQuery.Include(“Properties.OMRBuildingSurveys”)
要加载调查详细信息,我们捕获了属性选择器列表框已更改事件,这是我们可以按如下方式过滤的地方:
Private Sub Lbx_PropsByNameSelector_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles Lbx_PropsByNameSelector.SelectionChanged
Dim propertyAdListBox = CType(sender, ListBox)
Dim selectedProperty = CType(propertyAdListBox.SelectedItem, OMRInterfaceCustomCode.Property)
If Not IsDBNull(selectedProperty) Then
Dim RSurveysQuery = From r In OMRInterfaceEntities.OMRBuildingSurveys Where r.PeriodID > 80 And r.PropertyID = selectedProperty.ID
Dim RSurveysList = RSurveysQuery.ToList
If RSurveysList.Any() Then
Dim RecentSurveysSource = CType(Me.FindResource("OMRMarketsPropertiesOMRBuildingSurveysViewSource"), CollectionViewSource)
RecentSurveysSource.Source = RSurveysList
End If
End If
End Sub