0

我正在尝试使用对象查询跨多个实体关系进行查询。

实体链基本上就是OMRMARKET(一对多)PROPERTIES(一对多)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)))

我得到了智能感知支持,可以帮助我建立该查询,但后来我得到了错误

'System.Collections.Generic.IEnumerable(Of OMR.OMRInterfaceCustomCode.OMRBuildingSurvey)' 类型的值无法转换为 'Boolean'

任何帮助将不胜感激。我知道这一定是可行的。首先十分感谢。

4

2 回答 2

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>谓词的子句......所以看起来我们已经找到了错误。

更新>>>

好的......根据我的更好判断,我会试一试,因为我对你的课程结构视而不见。

从右侧开始,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类型,其中包含具有满足其(CLR)属性中的谓词条件的Property任何实例的项目。该方法将每个属性的值与满足谓词条件的实例的输出连接起来,并返回任何相同的值。OMRBuildingSurveyPeriodIDOMRBuildingSurveysIntersectOMRBuildingSurveysIEnumerableOMRBuildingSurveyAny

最后一步是这样的:

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。现在,我希望这行得通,因为我没有更多的时间来做这件事了。此外,由于我编写 C#,VB可能已“关闭”,但我相信如果此示例不起作用,您可以使用我提供的信息完成此操作......当您破坏它们时,这些查询并不是那么糟糕像我一样倒下。

顺便说一句,此示例遵循您问题中的要求,而不是您上一条评论中的要求。

于 2013-09-03T09:55:13.433 回答
0

好的,答案很简单。

在使用 Eager Loading 或 Lazy Loading 时,您无法过滤。我和几个自由职业者尝试了各种方法,但答案是加载市场和属性,然后注释掉以下代码行:

'OMRMarketsQuery = OMRMarketsQuery.Include("Properties.OMRBuildingSurveys")

为了加载调查详细信息,我们捕获了 Property Selector 列表框更改事件,我们可以在其中进行如下过滤:

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
于 2013-09-11T00:06:31.680 回答