【问题标题】:Filtering or removing from a list(Of T)过滤或从列表中删除(Of T)
【发布时间】:2012-09-22 21:54:43
【问题描述】:

我有一个采用对象列表的方法。
在持久化对象之前,我必须在某些给定条件下删除其中一些

例如(不是理想的!):

公司可以有一个 ID 和一个分支机构列表和一个 IsDeleted 标志。
一个分支可以有一个 ID 和一个经理列表和一个 IsDeleted 标志
经理可以有一个 Id 和一个 IsDeleted 标志
公司-->分支机构-->经理

什么是最简单或最好的过滤方式来省略 Id = 0 和 IsDeleted = True 的组合,所以我可以对其进行迭代并做具体说明——请参阅下面的函数

  • 如果公司被标记为Id = 0 and IsDeleted,那么我想完全省略它
  • 但是如果只有 Branch 被标记为Id=0 and Isdeleted 那么公司应该没有 Branch
  • 如果只有经理被标记为Id=0 and Isdeleted,那么公司和分公司应该在那里

Private Function(comp as List(Of Company)) as Boolean
    'filter comp here and pass it to for loop??
    Dim filteredList as ...
    For each c as Company in filteredList 
    'do company specifis here
        For each b as Branch in c.Branches
        'do branch specific here
            For Each m as Manager in b.Managers
            'do manager specific here
            Next
        Next
    Save(c) ' saves child objects as well    
    Next
End Function

【问题讨论】:

    标签: .net vb.net generics


    【解决方案1】:

    你可以使用 Linq:

    Dim filtered = From c In comp Where Not c.IsDeleted OrElse c.Id <> 0
                 From b In c.Branches Where Not b.IsDeleted OrElse b.Id <> 0
                 From m In b.Managers Where Not m.IsDeleted OrElse m.Id <> 0
                 Select New With {.Company = c, .Branch = b, .Manager = m}
    
    For Each x In filtered
        Dim c As Company = x.Company
        Dim b As Branch = x.Branch
        Dim m As Manager = x.Manager
    Next
    

    或者,如果您想分别枚举每种类型:

    Dim filteredComp = From c In comp Where Not c.IsDeleted OrElse c.Id <> 0
    Dim filteredBranch = From c In filteredComp
                       From b In c.Branches Where Not b.IsDeleted OrElse b.Id <> 0
                       Select b
    Dim filteredManager = From b In filteredBranch
                       From m In b.Managers Where Not m.IsDeleted OrElse m.Id <> 0
                       Select m
    
    For Each c In filteredComp
    
    Next
    For Each b In filteredBranch
    
    Next
    For Each m In filteredManager
    
    Next
    

    【讨论】:

      【解决方案2】:

      这能解决您的问题吗?

      Dim filtererdComp = comp _
          .Where(Function(c) c.Id<>0 Or Not c.IsDeleted)
          .ToList()
      For each c as Company in filtererdComp
          c.Branches = c.Branches _
              .Where(Function(b) b.Id<>0 Or Not b.IsDeleted) _
              .ToList()
          For each b As Branch in c.Branches
              b.Managers = b.Managers _
                  .Where(Function(m) m.Id<>0 Or Not m.IsDeleted) _
                  .ToList()
          Next
      Next
      

      【讨论】:

      • 谢谢,我可以看到您首先过滤了我理解的公司。但是 filtererdComp 仍然可以在分支中包含不需要的条目,所以我猜c.Branches = c.Branches .Where(Function(b) b.Id&lt;&gt;0 Or Not b.IsDeleted).ToList() 将分支重置为 where 条件?
      • 首先我创建了一个过滤公司的列表。然后,我将每个过滤后的公司中的分支机构列表替换为过滤后的分支机构列表,最后将每个过滤后的分支机构中的每个经理列表替换为过滤后的经理列表。结果是过滤管理器列表,其中包含过滤管理器的过滤分支。
      • 你不是在改变原来的 Company 和 Branch 对象吗?我不确定这是需要的。
      • 是的,这会改变原始对象。如果它们被标记为 IsDeleted 并且 ID 为 0,则可以摆脱它们。 Tim Schmelter 的解决方案保持原始对象不变。由 OP 决定。
      • @MarkJ 我使用实体框架来保存更改。所以从原件中删除是我所需要的。
      【解决方案3】:

      在迭代的每个级别中,循环遍历该级别上的所有现有元素。使用 if 语句检查 ID=0 和 IsDeleted 是否为真,在这种情况下删除条目。

      【讨论】:

        猜你喜欢
        • 2010-10-07
        • 1970-01-01
        • 2010-09-20
        • 1970-01-01
        • 2020-08-31
        • 2013-04-22
        • 1970-01-01
        • 2023-03-25
        • 2022-01-22
        相关资源
        最近更新 更多