从匹配ID的不同列表添加属性

时间:2019-04-18 17:09:24

标签: c# .net linq

我正在从具有相同ID的两个来源中提取数据。一组数据具有元数据,而另一组则没有。最后,我要列出一个具有共同信息的列表。

public class Record
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Title { get; set; }
    public string MetaInfo1 { get; set; }
    public string MetaInfo2 { get; set; }

}
List<Record> doc = new List<Record>(); //About 100k items, MetaInfo is null

List<Record> docWithMeta = new List<Record>(); //About 50k items, Name and Title Null

我尝试使用Join,但是第二个数据集并不总是具有匹配的ID,最终结果是一个List,仅包含具有匹配项的项目。最终结果应该具有缺少元数据的记录,这是可以的。

var joint = doc.Join(docWithMeta,
            a => a.Id,
            b => b.Id,
            (a, b) => new Record
            {
                Id = a.Id,
                Name = a.Name,
                Title = a.Title,                        
                MetaInfo1 = b.MetaInfo1,
                MetaInfo2 = b.MetaInfo2,
            }).ToList();

我尝试使用嵌套的foreach循环来查找匹配项并将属性添加到新列表中,该列表可以正常工作,但是代码非常慢。

List<Record> newDoc = new List<Record>();

foreach (Record rec in doc)
{
   foreach (Record recMeta in docWithMeta)
   {
      if (rec.Id == recMeta.Id)
      {
         rec.MetaInfo1 = recMeta.MetaInfo1;
         rec.MetaInfo1 = recMeta.MetaInfo1;
      }
   }
   newDoc.Add(rec);
}

我也尝试过使用GroupJoin,但是我不确定如何使用它,并且不断收到null异常。

var results = doc.GroupJoin(docWithMeta,
              a => a.Id,
              b => b.Id,
              (a, result) => new Record
              { 
                 Id = a.Id,
                 MetaInfo1 = result.FirstOrDefault().MetaInfo1 //null exception here
              }).ToList();

更新

使用下面的一些建议,我得到了一种性能足够好的方法。

var results = doc.GroupJoin(docWithMeta,
           a => a.Id,
           b => b.Id,
           (a, result) => new 
           { 
             Foo = f,
             Bar = result }      
           }).SelectMany(
              x => x.Bar.DefaultIfEmpty(),
              (x, y) => new Record
              {
                 Id = x.Foo.Id,
                 Name = x.Foo.Name,
                 MetaInfo1 = y == null ? null : y.MetaInfo1,
                 MetaInfo2 = y == null ? null : y.MetaInfo2
              }).ToList();

每当包含元数据的数据集没有与第一个数据集匹配的ID时,我都会一直获取NullReferenceException。我只是使用三元运算符来检查null。必须有更好的方法。

1 个答案:

答案 0 :(得分:1)

我现在无法检查此代码,但我认为它一定可以工作

doc.GroupJoin(
      docWithMeta,
      a => a.Id,
      b => b.Id,
      (a, b) => new { doc = a, meta = b })
  .SelectMany(
      ab => ab.docWithMeta.DefaultIfEmpty(),
      (x, y) => new { doc = x.doc, meta = y })
  .Select(s => new
  {
      Id = s.doc.Id,
      Name = s.doc.Name,
      Title = s.doc.Title,                        
      MetaInfo1 = s.meta?.MetaInfo1 == null ? "" : s.meta?.MetaInfo1,
      MetaInfo2 = s.meta?.MetaInfo2 == null ? "" : s.meta?.MetaInfo2,  
  }).ToList();