在C#中的多个列上按结构列表分组

时间:2016-09-24 06:07:31

标签: c# linq

我有一个结构

public struct structMailJob
{
 public string ID;
 public string MailID;
 public int ResendCount;
 public int PageCount;
}

和列表

List<structMailJob> myStructList = new List<structMailJob>();

我已经从数据库中加载了 myStructList 中的数据,并在通过MailID和ResendCount进行分组后将myStructList数据放在一个新列表中。

我正在尝试:

List<structMailJob> newStructList = new List<structMailJob>();

newStructList = myStructList.GroupBy(u => u.MailID, u=>u.ResendCount)
                                  .Select(grp => new { myStructList = grp.ToList() })
                                  .ToList();

但无法做到这一点,因为收到错误消息 - 无法将通用列表隐式转换为structMailJob。

4 个答案:

答案 0 :(得分:2)

我认为您正在寻找以下内容:

var newStructList = myStructList.GroupBy(smj => new { smj.MailID, smj.ResendCount })
                                .Select(grp => new 
                                { 
                                    MailID = grp.Key.MailID,
                                    ResendCount = grp.Key.ResendCount
                                    MailJobs = grp.Select(x=>new 
                                               {
                                                   x.ID,
                                                   x.PageCount
                                               }).ToList() 
                                })
                                .ToList();

请注意,我们将GroupBy子句更改为以下选项:

GroupBy(smj => new { smj.MailID, smj.ResendCount })

这样做,创建组的密钥将由MailIDResendCount组成。顺便说一下,前GroupBy条款是不正确的。

然后完成分组后,我们将每个组投影到一个具有三个属性MailIDResendCout的对象,这三个属性是密钥的组件,具有两个属性的匿名类型对象列表{ {1}}和ID,我们将其命名为MailJobs。

最后但并非最不重要的是,您会注意到我没有提及以下

PageCount

我刚使用了List<structMailJob> newStructList = new List<structMailJob>(); 并宣布了var。我认为你在帖子中说明没有意义。在对它们进行分组后,我们如何获得相同对象的列表?所以我假设你可能想要的是上面的。

但是,我认为你可能也想要这样的东西而你并不想参考分组

newStructList

答案 1 :(得分:1)

Linq查询完全不正确,以下是重点:

myStructList.GroupBy(u => u.MailID, u=>u.ResendCount) //分组错误

myStructList.GroupBy(u => new {u.MailID, u.ResendCount }) //正确分组,由MailIDResendCount两列完成,最后一个仅由MailID进行并使用ResendCount用于结果投影

现在结果属于IEnumerable<IGrouping<AnonymousType,structMailJob>>类型,因此当您执行Select之类的操作时,最终会创建类型为IEnumerable<List<structMailJob>>的连续列表(已删除对myStructList的分配在Select中,因为这不正确):

.Select(grp => grp.ToList())

正确的代码需要您使用SelectMany展平,如下所示:

newStructList = myStructList.GroupBy(u => new {u.MailID, u.ResendCount})
                                      .SelectMany(grp => grp.ToList()).ToList();

将其分配给newStructList,但此代码几乎没有用,因为字面上newStructListmyStructList后扁平化完全相同,理想情况下,您应该可以使用分组,这样您可以获得一个子集,从而获得正确的结果,但这取决于您的业务逻辑

答案 2 :(得分:0)

我不知道我的问题是否正确,但在我看来,你错过了'分组'签名。

List<structMailJob> myStructList = new List<structMailJob>();

List<structMailJob> newStructList = new List<structMailJob>();

newStructList = myStructList
    // .GroupBy(/*Key Selector */u => u.MailID, /*Element Selector*/u=>u.ResendCount)           
    .GroupBy(u => new { u.MailID, u.ResendCount }) // broup by MailID, ResendCount
    // Note no Element Selector , the 'STRUCT' is 'SELECTED'
    .Select(grp => {
        // NOte: Key ==  Anonymous {MailID, ResendCount } 
        return grp;
    })
    // otherwise you get a IEnumerable<IEnumerable<T>> instead of IEnumerable<T> because you grouped it
    .SelectMany(x=>x)
    .ToList();  

答案 3 :(得分:0)

如果您正在寻找Mrinal Kamboj的答案,那么您可以使用以下内容作为替代方案:

  var orderedList = myStructList.OrderBy(x => x.MailID).ThenBy(x => x.ResendCount);