为了账号安全,请及时绑定邮箱和手机立即绑定

c#将列表分组到新列表中

c#将列表分组到新列表中

C#
猛跑小猪 2021-11-21 14:38:15
我遇到了无法将列表分组的问题,我进行了研究并尝试了不同的方法,但结果不是我想要的。我不确定我是否做错了什么。List<NewSomeGroup> newsomegourplist = new List<NewSomeGroup>();var query = from c in _someRepository.Table                            where  c.isRead == false                            group c by c.ReferenceId into grpdlist                            orderby grpdlist.Key                            select grpdlist;foreach (var grpdlist in query){    NewSomeGroup somegroup = new NewSomeGroup();    List<Some> somelist = new List<Some>();    somegroup.ReferenceId = grpdlist.Key;    foreach (var item in grpdlist) // not in    {        somelist.Add(item);    }    somegroup.somecontainlist = somelist;    newsomegourplist.Add(somegroup);}最后somegroup有正确ReferenceId但somecontainlist有空的对象。我很确定它在数据库中有数据,我也尝试在 localhost 中调试,发现它//not in没有添加item.数据结构public class NewSomeGroup{    public string ReferenceId { get; set; }    public List<Some> sbnotificationlist { get; set; }}public class Some{    public string Title { get; set; }    public string projectid { get; set; }    public SimpleAccountInfo AccountInfo { get; set; }    public string Type { get; set; }     public string ReferenceId { get; set; }    public string iconPath { get; set; }    public DateTime CreateOnUtc { get; set; }}
查看完整描述

2 回答

?
狐的传说

TA贡献1804条经验 获得超3个赞

唉,你没有指定你的Table,所以我必须从你的代码中提取规范:


输入是一个Table行,其中每一行都是一个对象,至少有一个布尔属性IsRead和一个属性ReferenceId。


此外,似乎每一行都类似于Some. A row 不等于 a Some,因为 rows 有一个属性IsRead而 aSome没有这个属性。


这可能是输入错误,或者行可能是Some. 由于您没有指定您的表,我将假设后者。


表中的行不必是相同类型的对象,但它们至少来自 Some


您希望将所有尚未读取的行分组为具有相同ReferenceId. 您希望每个组都转换为一个NewSomeGroup对象,其中ReferenceId是ReferenceId组中元素的公共项,SbNotificationList是一个列表,其中每个元素包含Some组中行的值。


我更熟悉方法语法(除了它有更多功能),所以我的答案将是方法语法:


var result = myRepository.Table           // from every row in the Table

    .Where(row => !row.IsRead)            // take only those that are not read

    .GroupBy(row => row.ReferenceId)      // make groups of rows with equal ReferenceId

    .Select(group => new NewSomeGroup()   // from every group make one NewSomeGroup object

    {

         ReferenceId = group.Key,

         SbNotificationList = group       // from the sequence of rows in the group

             .Cast<Some>()                // cast every row to a Some

             .ToList(),                   // and put it in a list

    })

    .OrderBy(item => item.ReferenceId);

只有当您绝对确定表中的每一行确实是一个Some.


这是最有效的,因为您的行不会被复制;参考资料放在您的最终结果中。或者换句话说:您的最终结果包含原始行。


但是,这会导致如果您更改 SbNotificationList 元素的属性值,则原始行将更改。


如果您不想要这个,或者某些行不是Some您必须Some使用行中的值创建新对象:


.GroupBy(row => row.ReferenceId)

.Select(group => new NewSomeGroup() 

{

    ReferenceId = group.Key,

    SbNotificationList = group       // from the rows in the group make one list

        .Select(row => new Some()    // where every row becomes one Some object

        {

            Title = row.Title,

            ProjectId = row.ProjectId,

            ...

            CreateOnUtc = row.CreateOnUtc, 

         })

         .ToList(),

})

.OrderBy(item => item.ReferenceId);

无论您选择哪种方法,如果您的输入表为空或没有未读取的行,您的结果仍将是一个NewSomeGroup对象序列,但是该序列将为空(这与 null 不同!)。


如果您的输入表有一行或多行被读取,您的结果不会为空。NewSomeGroup结果中的每一个都将有一个非空的SbNotificationList,包含与对象的 ReferenceId 相等Some的所有行的值。ReferenceIdNewSomeGroup


很难说NewSomeGroup最终结果中的任何对象都不能有一个空的SbNotificationList. 你可以Debug.Assert在这个


查看完整回答
反对 回复 2021-11-21
?
茅侃侃

TA贡献1842条经验 获得超21个赞

你可以试试下面的代码:

somegroup.somecontainlist.AddRange(somelist);

或者你可以试试这个:

somegroup.somecontainlist = new List<SomeDataType>(somelist);

或者,如果您使用的是 C# 3 和 .NET 3.5,则可以通过 Linq 执行以下操作:

somegroup.somecontainlist = somelist.ToList();


查看完整回答
反对 回复 2021-11-21
  • 2 回答
  • 0 关注
  • 197 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信