遍历一个 IQueryable(ObjectS)并检查一个属性是不是存在于另一个 ASQueryable(ObjectS)中

Posted

技术标签:

【中文标题】遍历一个 IQueryable(ObjectS)并检查一个属性是不是存在于另一个 ASQueryable(ObjectS)中【英文标题】:Loop through a IQueryable (of ObjectA) and check if a property exists in another IQueryable (of ObjectB)遍历一个 IQueryable(ObjectS)并检查一个属性是否存在于另一个 ASQueryable(ObjectS)中 【发布时间】:2020-02-12 09:04:12 【问题描述】:

我有两个 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 中?

【问题讨论】:

您的问题很难理解 - 有很大的解释空间。试着澄清你的问题。举个例子。预期的输入和输出。对象模型。不惜一切代价让事情变得易于理解。 【参考方案1】:

您可以使用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

【讨论】:

【参考方案2】:

您可以使用 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。

【讨论】:

【参考方案3】:

您可以使用快捷方式并直接从源列表中创建 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

希望对你有帮助。

【讨论】:

您可能应该包含您的ForEach extension method 以完成此操作 好的,我会解决的。 在制作两个列表时,我会以与此类似的方式处理问题(我有自己的 ForEach ......)。您甚至可以在选择中包含 Selected 属性和 ID / 0。我正在考虑使用JOIN,但这里已经有两个很好的答案,包括这个! 我也发布了一个答案。对于你来说,我指的是ForEach不是IEnumerable/IQueryable的成员,而且很多人使用它,但它必须在扩展方法中。如果导航到定义,您将看到它不在 .NET 框架中。

以上是关于遍历一个 IQueryable(ObjectS)并检查一个属性是不是存在于另一个 ASQueryable(ObjectS)中的主要内容,如果未能解决你的问题,请参考以下文章

C# 向IQueryable添加一个Include扩展方法

C#怎么遍历IQueryable<Infrom>Inform为数据库类型

遍历集合项并检查每个属性的有效值

EF入门 IQueryable和IEnumberable的区别

EF下怎么理解IEnumerable/ICollection/IQueryable?

从 Entity Framework Core IQueryable<T> 获取 SQL 代码