循环遍历(ObjectA 的)IQueryable 并检查 属性 是否存在于另一个 IQueryable(ObjectB 的)中

Loop through a IQueryable (of ObjectA) and check if a property exists in another IQueryable (of ObjectB)

我有两个 IQueryable,wsSelectedAppsallApps。我需要遍历 allApps 中的每个应用程序并检查 属性 app.AppID 是否存在于我的其他 IQueryable 中。

到目前为止我的代码是....

Dim wsSelectedApps = (From i In de.vw_AppsForWsList
                      Where i.WSID = WSID
                      Select i.ID, i.AppID)

Dim allApps = (From a In de.TblApps
               Select a.AppID, a.AppName)

Dim appList As New List(Of DeploymentModel)

For Each app In allApps
    'Loop through allApps and build up appList

    If xxxxxxxxxx Then
        'this app exists in wsSelectedApps
        appList.Add(New DeploymentModel With {
            .AppID = app.AppID,
            .AppName = app.AppName,
            .ID = wsSelectedApps.ID,
            .Selected = True})
    Else
        'this app does not exist in wsSelectedApps
        appList.Add(New DeploymentModel With {
            .AppID = app.AppID,
            .AppName = app.AppName,
            .ID = 0,
            .Selected = False})
    End If
Next

IF语句原来有

If wsSelectedApps.Contaings(app.AppID) Then...

wsSelectedApps 只是 AppIDs 的列表时这很好,但它现在包含两个属性。如何检查 app.AppID 是否存在于 wsSelectedApps 中?

您可以使用 System.LINQ 提供的 Any() 扩展程序。
您的 if 条件将如下所示

For Each app In allApps
    If wsSelectedApps.Any(Function(selected) selected.AppID = app.AppID) Then
        'Do something
    Else
        'Do something else
    End if
Next

您可以使用快捷方式直接从源列表创建 True、False 列表,如下所示:

Dim TrueList = (From a As DeploymentModel In de.TblApps, b As DeploymentModel In de.vw_AppsForWsList Where b.WSID = WSID AND  a.AppID = b.AppID Select a).ToList
Dim FalseList = de.TblApps.Except(TrueList).ToList

除非您需要创建新的 DeploymentModel 对象列表,否则您可以修改 DeploymentModel 对象的属性,如下所示:

TrueList.ForEach(Sub(a)
                    a.Selected = True
                    a.ID = ...
                    '...
                End Sub)

FalseList.ForEach(Sub(a)
                    a.Selected = False
                    a.ID = ...
                    '...
                End Sub)

并且,下面是快速测试的输出:

True List:

Id: 2, AppId: 1002, AppName: Application 2, Selected: True
Id: 4, AppId: 1004, AppName: Application 4, Selected: True
Id: 6, AppId: 1006, AppName: Application 6, Selected: True
Id: 8, AppId: 1008, AppName: Application 8, Selected: True
Id: 10, AppId: 1010, AppName: Application 10, Selected: True

False List:

Id: 1, AppId: 1001, AppName: Application 1, Selected: False
Id: 3, AppId: 1003, AppName: Application 3, Selected: False
Id: 5, AppId: 1005, AppName: Application 5, Selected: False
Id: 7, AppId: 1007, AppName: Application 7, Selected: False
Id: 9, AppId: 1009, AppName: Application 9, Selected: False

希望对您有所帮助。

您可以在 LINQ 中使用左外连接来实现这一点。这类似于 SQL,但使用 LINQ,您可以在未找到匹配项时指定默认值。我希望这对你有用 - 我在你的数据库架构知识有限的情况下做了尽可能多的工作。

Dim appList =
    (From a In de.tblApps
     Group Join s In de.vw_AppsForWsList On a.AppID Equals s.AppID Into Group
     From p In Group.DefaultIfEmpty(New AppsForWsList With {.AppID = a.AppID, .AppName = a.AppName, .ID = 0})
     Select New DeploymentModel With {.AppID = p.AppID, .AppName = p.AppName, .ID = p.ID, .Selected = p.ID <> 0}).ToList()

有关 vb.net LINQ 左外连接的更多信息,请参见 this answer