我有以下用例:

Account Name  |  Ref 1 | Ref 2

Account1      |   Mike | John
Account1      |        |
Account1      |        |
Account2      |   Carl | Mike
Account2      |   Carl | Mike


具有相同AccountName,Ref1,Ref2的行应合并在一起,但是


  如果包含空的Ref1或Ref2,则不应合并。


结果应为:

Account Name  |  Ref 1 | Ref 2

Account1      |   Mike | John
Account1      |        |
Account1      |        |
Account2      |   Carl | Mike



  AccountViewModel具有属性:AccountName,Ref1,Ref2




var result = new List<AccountViewModel >();

source.GroupBy(vm => new { vm.AccountName, vm.Ref1, vm.Ref2})
                  .Select(group =>
                  {
                      if (group.All(vm => string.IsNullOrWhiteSpace(vm.Ref1)) ||
                          group.All(vm => string.IsNullOrWhiteSpace(vm.Ref2)))
                      {
                          result.AddRange(group);
                      }
                      else
                      {
                          result.Add(new AccountViewModel
                          {
                              AccountName = group.Key.AccountName,
                              Ref1= group.First().Ref1,
                              Ref2= group.First().Ref2
                          });
                      }
                  });

 return result;


我是否缺少GroupBy的功能?可以用其他方式完成吗?

最佳答案

三个建议。

首先,您可以使用SelectMany将每个组映射到一个项目序列,并为您合并序列,而不是使用Select并将其作为副作用添加到列表中。

其次,您不必检查整个组的null /空格-您已经按这些值进行了分组,因此它们对于组中的每个项目都应相同。您只需检查密钥即可。

第三,如果不想的话,不需要创建新的AccountViewModel来代表组-您可以只使用组中的第一项。

return source
    .GroupBy(vm => new { vm.AccountName, vm.Ref1, vm.Ref2})
    .SelectMany(group =>
        {
            if (string.IsNullOrWhiteSpace(group.Key.Ref1) ||
                string.IsNullOrWhiteSpace(group.Key.Ref2))
            {
                // keep the group separate
                return (IEnumerable<AccountViewModel>)group;
            }
            else
            {
                // just use one item
                return new[] { group.First() };
            }
        });

10-06 07:27