如何使用 linq 正确检测另一个元素中不存在的元素

本文关键字:元素 不存在 另一个 检测 何使用 linq | 更新日期: 2023-09-27 18:37:05

我在数据库中有一个表,记录与用户配置文件相关的打印机。我的数据库看起来像这样:

|Date | UserID | PcId | PrinterId | ConfigId
|...  |   1    |   1  |    1      |     1
|...  |   1    |   1  |    2      |     2
|...  |   1    |   1  |    3      |     3
|...  |   1    |   1  |    4      |     4    

我正在使用 WCF 服务以 dB 格式上传有关打印机的新信息。用户可以从其本地配置文件中删除打印机。在这种情况下,当完成下一次信息时,必须从数据库中删除此打印机。

我的目标是将新打印机名称与 db 中记录的打印机名称(与用户/PC 相关)进行比较,如果 db 中的打印机名称在新列表中不存在,我必须将其从数据库中删除,因为此打印机不再使用。

我的方法不起作用,因为它始终是打印机列表中的第一个元素被删除,而不是好的元素。例如,如果我想删除打印机 ID #4,则删除的是 #1。

这是我的方法

//Printers related to user/pc
var ptrInList = context.AuditPrinters.Include(a => a.PrintersConfigs)
                        .Include(a => a.Printers)
                        .Where((c => c.UserId == userInDb && c.PcId==pcInDb))
                        .ToList();
//Iteration on fresh data from client
foreach (var p in data)
{
    var printersInDb = ptrInList
        .SingleOrDefault(c => c.Printers.PrinterName == p.Printer); // runs in memory
    if (printersInDb != null)
    {
        AuditPrinters apt = context.AuditPrinters
            Where(t => t.PrinterId == printersInDb.PrinterId &&
                      t.PcId==pcInDb && t.UserId==userInDb)
            .FirstOrDefault();
        apt.Date = DateTime.Now;
        PrintersConfigs cfg = context.PrintersConfigs
            .Where(t => t.ConfigId == printersInDb.ConfigId).FirstOrDefault();
        cfg.IsDefault = bool.Parse(p.Default);
    }
    else
    {
        var RF = new AuditPrinters() 
        { 
            Date = DateTime.Now, 
            UserId = userInDb, 
            PcId = pcInDb 
        };
        var PTR = new Printers() 
        { 
            PrinterServ = p.PrinterSrv,
             PrinterName = p.Printer
        };
        var CFG = new PrintersConfigs() { IsDefault = bool.Parse(p.Default) };
        PTR.AuditPrinters.Add(RF);
        CFG.AuditPrinters.Add(RF);
        context.Set<Printers>().Add(PTR);
        context.Set<PrintersConfigs>().Add(CFG);
    }
}
//List of printers name in fresh data
var ptr = data.Select(c => c.Printer).ToList();
foreach (var p in ptrInList)
{
    AuditPrinters printerToDelete = context.AuditPrinters
        .Where(u => !ptr.Contains(p.Printers.PrinterName) && 
            (p.UserId == userInDb) && (p.PcId == pcInDb))
        .FirstOrDefault();
    if (printerToDelete != null)
        context.AuditPrinters.Remove(printerToDelete);
}

如何使用 linq 正确检测另一个元素中不存在的元素

我找到了这个工作解决方案,除了:

var ptrNotInList = ptrInList.Select(t => t.Printers.PrinterName)
          .Except(data.Select(e => e.Printer))
          .ToList();
if (ptrNotInList != null)
{
    foreach (var m in ptrNotInList)
    {
        AuditPrinters printerToDelete = (from t in context.AuditPrinters where t.Printers.PrinterName == m && t.PcId==pcInDb && t.UserId==userInDb select t).SingleOrDefault();
        context.AuditPrinters.Remove(printerToDelete);
    }
}
context.SaveChanges();