Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在匹配的ID上添加来自不同列表的属性_C#_.net_Linq - Fatal编程技术网

C# 在匹配的ID上添加来自不同列表的属性

C# 在匹配的ID上添加来自不同列表的属性,c#,.net,linq,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 M

我从两个具有公共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
我尝试使用嵌套的
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);
}
更新

使用下面的一些建议,我得到了一个运行良好的方法

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
。一定有更好的方法。

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

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

我认为这个例子会有所帮助-关键是DefaultOrEmpty()调用-使用left-outer-join:Thank的Sam。使用你的例子帮助我朝着正确的方向前进,但是,每当元数据集中没有匹配的记录时,我总是得到一个nullreferenceexception。每当元数据集中没有匹配的记录时,我仍然会得到一个nullreferenceexception。具体在哪里得到这个异常?“MetaInfo1=s.meta.MetaInfo1”元为null,它抛出一个异常OK,我更改了解决方案,我认为必须解决你的问题
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();
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();