【问题标题】:How to return records not found in both lists using c# and linq如何使用 c# 和 linq 返回在两个列表中都找不到的记录
【发布时间】:2015-05-13 10:21:40
【问题描述】:

我是 linq 新手,我真的很难从第二个表中不存在记录的两个列表中获取结果。

我两个班……

  • cfiles

    • 年份
    • 会话
    • 中心
    • fileNameRaw
  • cfileRecs -Id

    • 文件名

cfiles,包含存储库中的所有pdf文件,其中cfilesRecs包含每个pdf文件的数据库条目。

这两个类都显示为 List 和 List,我想返回一个列表,其中仅包含使用 linq 在 cfilesRecs 中找不到的文件。

这是使用的代码,尽管您可能看到 linq 语法是错误的。

public static void Main(string[] args)
    {
        List<cfileRecs> dbScanRecords = dbRecords();    // Contains db records for objects
        List<cfiles> awsScanObjects;                   // Contains objects from aws
        using (client = new AmazonS3Client(Amazon.RegionEndpoint.EUWest1))
        {
            Console.WriteLine("Listing objects stored in a bucket");
            awsScanObjects = ListingObjects();
        }

        List<cfiles> abc = from d in dbScanRecords join aws in awsScanObjects on d.fileName == aws.fileNameRaw

    }

示例答案主要涉及与相同类型的列表进行比较 - 而不是将两个不同的列表连接到一个共同的属性值上。

感谢大家提供的示例,但它们似乎没有产生正确的结果我创建了一个 dotnetfiddle https://dotnetfiddle.net/MW6gXF 来说明问题。结果返回 6 个项目,我应该只得到 3 个。

【问题讨论】:

标签: c# linq


【解决方案1】:

您可以将Where()Any() 结合使用来实现:

var result = awsScanObjects.Where(x=> !dbScanRecords.Any(y=> y.filenameRaw == x.filename));

【讨论】:

  • 这不会编译由于y.filenameRaw =x.filename你必须使用等于运算符==
  • 当我尝试这个时,where 子句中的所有内容都出现错误 - 未知方法 Where?
  • 你是否包含了 System.Linq 命名空间
  • 是 System.Linq 命名空间包括在内。
  • 你能在 Dotnetfiddle.net 中重现
【解决方案2】:
var result = awsScanObjects.Where(r => !dbScanRecords.Any(r2 => r2.fileName == r.fileNameRaw));

【讨论】:

    【解决方案3】:
    var files = dbScanRecords.Select(x => x.fileName).ToList();
    
    result = awsScanObjects.Where(x => !files.Contains(x.fileNameRaw)).ToList();
    

    【讨论】:

      【解决方案4】:

      查找存在于 AWS 但不存在于 dbrecords 中的文件。

      private class cfileRecs
              {
      
                  public int Year { get; set; }
                  public string session { get; set; }
                  public string center { get; set; }
                  public string fileNameRaw { get; set; }
      
              }
      
              private class cfiles
              {
                  public string FileName { get; set; }
              }
      
      List<cfileRecs> dbScanRecords = new List<cfileRecs>() { 
                      new cfileRecs(){ center = "a", fileNameRaw ="abc.pdf", 
                      session="aaa", Year=1999}};    
      
      List<cfiles> awsScanObjects = new List<cfiles>() { 
                      new cfiles(){ FileName = "abc.pdf"},
                      new cfiles(){ FileName = "bbb"}
                  };
      
      var filesNotFound = (from files in awsScanObjects
                        join recs in dbScanRecords 
                        on files.FileName equals recs.fileNameRaw into grp
                        from g in grp.DefaultIfEmpty()
                        select new { dbfile = g == null ? null : g.fileNameRaw,
                        awsfile = files.FileName })
                         .Where(x => x.dbfile == null).ToList();
      

      fileNotFound 包含文件名为“bbb”的 AWS 记录,但在 dbrecord 中找不到

      【讨论】:

      • filesNotFound 包含 awsScanObjects 中的总记录 - awsScanObjects 中大约有 55,000 个文件,而 dbScanRecords 包含 9,600 条记录,所以我预计结果集约为 45,000 ish
      • 我已经用模型数据和查询结果更新了代码。我希望这会有所帮助。
      • 它返回文件的数量 - 我试图在 DotNetFiddle 中设置它,但不知道如何共享。找到了dotnetfiddle.net/MW6gXF
      【解决方案5】:

      //我知道您想查找存在于 AWS 但不存在于 dbrecords 中的文件。

      var filesNotFound =

      (从 awsScanObjects 中的文件加入 dbScanRecords 中的 recs

      在 files.FileName 上等于 recs.fileNameRaw 到 grp

      来自 grp.DefaultIfEmpty() 中的 g

      选择新的 { dbfile = g == null ? null : g.fileNameRaw, awsfile = files.FileName })

      .Where(x => x.dbfile == null).ToList();

      【讨论】:

      • 这会返回与 awsScanObjects 相同的行数(55,000 ish),dbScanRecords 中大约有 9,600 行 - 所以我预计大约 45,000 ish。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-20
      • 1970-01-01
      相关资源
      最近更新 更多