首页 > 解决方案 > 如何在具有嵌入列表的新重组对象列表中分发对象列表以更改根主键/索引?

问题描述

我想将 NoteModel 对象列表转换为对象列表,如下所示。

最终结果应包含包含日期的 GroupNoteModels 对象列表和具有相应日期的 GroupItemModel 对象列表。

public class NoteModel
{
    public DateTime Date { get; set; }
    public int NoteID { get; set; }
    public string Text { get; set; }
}

初始化并添加注释到noteList

private List<NoteModel> noteList = new List<NoteModel>();

public void AddNotes()
{
    aodList.Add(new AODModel(DateTime.Now, 1, "Text1"));
    aodList.Add(new AODModel(DateTime.Now.AddDays(1), 2, "Text2"));
    aodList.Add(new AODModel(DateTime.Now.AddDays(1), 3, "Text3"));
}

用于列表列表的模型

public class GroupItemModel
{
    public int NoteID { get; set; }
    public string Text { get; set; }
}

public class GroupedNoteModel
{
    public DateTime Date { get; set; }
    public List<GroupItemModel> noteWithSameDateList { get; set; }
}

我试过的代码

var noteGrouped = noteList.GroupBy(a => a.Date )
                    .Select(a => new
                    {
                        Date= a.Select(x=>x.Date ),
                        noteWithSameDateList= new {
                            NoteID = a.Select(x=>x.NoteID ),
                            Text= a.Select(x => x.Text)
                        } 
                    }).ToList();

List<GroupedNoteModel> noteGroupList = noteGrouped;

标签: c#linqobjectmodelgrouping

解决方案


循环解决方案

由于我并没有真正参与 SQL 和 LINQ 分组,我们可以编写它来分发数据:

var notesByDate = new List<GroupedNoteModel>();

foreach ( var note in notesById )
{
  GroupedNoteModel item = notesByDate.Find(n => n.Date == note.Date);
  if ( item == null )
  {
    item = new GroupedNoteModel();
    item.NoteWithSameDateList = new List<GroupItemModel>();
    item.Date = note.Date;
    notesByDate.Add(item);
  }
  var subitem = new GroupItemModel();
  subitem.NoteID = note.NoteID;
  subitem.Text = note.Text;
  item.NoteWithSameDateList.Add(subitem);
}

测试

var date = DateTime.Now;

var notesById = new List<NoteModel>();

notesById.Add(new NoteModel { Date = date.AddDays(0), NoteID = 1, Text = "Note 1" });
notesById.Add(new NoteModel { Date = date.AddDays(1), NoteID = 2, Text = "Note 2" });
notesById.Add(new NoteModel { Date = date.AddDays(2), NoteID = 3, Text = "Note 3" });
notesById.Add(new NoteModel { Date = date.AddDays(0), NoteID = 4, Text = "Note 4" });
notesById.Add(new NoteModel { Date = date.AddDays(2), NoteID = 5, Text = "Note 5" });

foreach ( var item in notesByDate )
{
  Console.WriteLine(item.Date);
  foreach ( var note in item.NoteWithSameDateList)
  {
    Console.WriteLine($"     {note.NoteID}: {note.Text}");
  }
}

输出

21/08/2021 07:56:11
     1: Note 1
     4: Note 4
22/08/2021 07:56:11
     2: Note 2
23/08/2021 07:56:11
     3: Note 3
     5: Note 5

干净的重构

除了为实体提供构造函数之外,可能还应该使用组合,NoteWithSameDateList否则在使用生成的分派数据时可能会出现空引用异常等问题:

了解聚合、关联、组合

关联,聚合和组合之间有什么区别?

foreach ( var note in notesById )
{
  GroupedNoteModel item = notesByDate.Find(n => n.Date == note.Date);
  if ( item == null )
  {
    item = new GroupedNoteModel(note.Date);
    notesByDate.Add(item);
  }
  item.NoteWithSameDateList.Add(new GroupItemModel(note.NoteID, note.Text));
}
notesById.Add(new NoteModel(date.AddDays(0), 1, "Note 1"));
notesById.Add(new NoteModel(date.AddDays(1), 2, "Note 2"));
notesById.Add(new NoteModel(date.AddDays(2), 3, "Note 3"));
notesById.Add(new NoteModel(date.AddDays(0), 4, "Note 4"));
notesById.Add(new NoteModel(date.AddDays(2), 5, "Note 5"));
public class NoteModel
{
  public DateTime Date { get; set; }
  public int NoteID { get; set; }
  public string Text { get; set; }
  public NoteModel(DateTime date, int id, string text)
  {
    Date = date;
    NoteID = id;
    Text = text;
  }
}

public class GroupItemModel
{
  public int NoteID { get; set; }
  public string Text { get; set; }
  public GroupItemModel(int id, string text)
  {
    NoteID = id;
    Text = text;
  }
}

public class GroupedNoteModel
{
  public DateTime Date { get; set; }
  public List<GroupItemModel> NoteWithSameDateList { get; }
  public GroupedNoteModel(DateTime date)
  {
    NoteWithSameDateList = new List<GroupItemModel>();
    Date = date;
  }
}

选择

public class GroupedNoteModel
{
    public DateTime Date { get; set; }
    public List<GroupItemModel> NoteWithSameDateList { get; }
      = new NoteWithSameDateList()
}

推荐阅读