简体   繁体   English

C#组列表到新列表

[英]c# group list into new list

I facing a issue that I cant group my list, I do research and tried different way, but the result is not I want. 我遇到一个问题,无法将我的列表分组,我进行了研究并尝试了不同的方法,但结果不是我想要的。 I not sure if I did something wrong. 我不确定自己做错了什么。

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);
}

At the end somegroup have correct ReferenceId but somecontainlist have empty object. 最后, somegroup具有正确的ReferenceId但是somecontainlist具有空对象。 I very sure it have data inside database, I also tried to debug in localhost and found it //not in doesn't Add the item . 我非常确定它在数据库中有数据,我也尝试在localhost中调试并发现它//not in not not add the item

Data Structure 数据结构

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; }
}

Alas you didn't specify your Table , so I'll have to extract the specifications from your code: las,您没有指定Table ,所以我必须从您的代码中提取规范:

input is a Table of rows, where every row is an object that has at least a Boolean property IsRead and a property ReferenceId . 输入是一个行Table ,其中每一行都是一个至少具有布尔属性IsRead和属性ReferenceId

Furthermore, it seems that every row is similar to a Some . 此外,似乎每一行都类似于Some A row is not equal to a Some , because rows have a property IsRead while a Some doesn't have this property. 行不等于Some ,因为行具有IsRead属性,而Some不具有此属性。

This could be a typing error, or rows could be objects from derived classes of Some . 这可能是键入错误,或者行可能是Some派生类中的对象。 As you didn't specify your table, I'll assume the latter. 由于您没有指定表,因此我假设后者。

Rows in your table don't have to be objects of equal type, but they are at least derived from Some 表中的行不必是相同类型的对象,但它们至少是从Some派生的

You want all rows that were not read yet, grouped into groups of rows with same ReferenceId . 您希望将所有尚未读取的行分组为具有相同ReferenceId的行组。 You want every group converted into one NewSomeGroup object, where the ReferenceId is the common ReferenceId of the elements in the group, and the SbNotificationList is a list, where each element contains the Some values of the rows in the group. 您希望将每个组转换为一个NewSomeGroup对象,其中ReferenceId是组中元素的公共ReferenceId ,而SbNotificationList是一个列表,其中每个元素都包含组中行的Some值。

I'm more familiar with method syntax (beside it has more functionality), so my answer will be in method syntax: 我对方法语法更加熟悉(除了它具有更多功能之外),所以我的答案将是方法语法:

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);

This will only work if you are absolutely certain that every row in your table really is a Some . 仅当您完全确定表中的每一行确实都是Some这才起作用。

This is the most efficient, because your rows are not copied; 这是最有效的,因为您的行没有被复制; the references are put in your final result. 参考资料将放入您的最终结果中。 Or in other words: your final result contains the original rows. 换句话说:您的最终结果包含原始行。

However, this has the effect that if you change the values of the properties of elements of your SbNotificationList, then the original rows will change. 但是,这样做的效果是,如果您更改SbNotificationList元素的属性值,则原始行将更改。

If you don't want this, or some rows aren't a Some you'll have to create new Some objects with the values from your rows: 如果您不希望这样做,或者某些行不是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);

Whatever method you choose, if your input table is empty or has no rows that aren't read, your result will still be a sequence of NewSomeGroup objects, however this sequence will be empty (that is something different than null!). 无论选择哪种方法,如果输入表为空或没有未读取的行,则结果仍将是NewSomeGroup对象的序列,但是此序列将为空(这与null有所不同!)。

If your input table has one or more rows that are read, your result won't be empty. 如果您的输入表中有一个或多个读取的行,则结果将不会为空。 Every NewSomeGroup in your result will have a non-empty SbNotificationList , containing the Some values of all rows that had a ReferenceId equal to the ReferenceId of the NewSomeGroup object. 结果中的每个NewSomeGroup都会有一个非空的SbNotificationList ,其中包含ReferenceId等于NewSomeGroup对象的ReferenceId的所有行的Some值。

That is a difficult way to say that it can't be that any NewSomeGroup object in your final result has an empty SbNotificationList . 很难说,最终结果中的任何NewSomeGroup对象都不具有空的SbNotificationList You can Debug.Assert on this 您可以在此进行Debug.Assert

You can try the below code: 您可以尝试以下代码:

somegroup.somecontainlist.AddRange(somelist);

or You can try this: 或者您可以尝试以下操作:

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

or if you're using C# 3 and .NET 3.5, with Linq, you can do this: 或者,如果您在Linq中使用C#3和.NET 3.5,则可以执行以下操作:

somegroup.somecontainlist = somelist.ToList();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM