首页 > 解决方案 > 使用 LINQ 识别重复的数据表行

问题描述

我有一个应用程序,用户在其中输入用于查询数据库并返回匹配行的搜索词。我想找到像这样重复的行:

File  Tool  Product  Time1          MeasureTime      Row
319   S32   AX       11/13 1:12AM   11/13 5:02am     5
318   S32   AX       11/13 1:12AM   11/13 4:41am     5

在这些情况下,具有较高文件 ID 的条目可能是错误的重新测量,因此我希望能够向用户突出显示这一点。

如果有重复的行,我有这段代码:

                    var duplicates = db2.AsEnumerable()
                    .GroupBy(r => new
                    {
                        Tool = r.Field<string>("Tool"),
                        Product = r.Field<string>("Product"),
                        Time1 = r.Field<DateTime>("Time1"),
                        Row = r.Field<Int32>("Row")
                    }).Select(g => new {
                        Tool = g.Key.Tool,
                        Product = g.Key.Product,
                        Time1 = g.Key.Time1,
                        Row = g.Key.Row,
                        Count = g.Count() }).ToList();

这将返回一个通用列表,我希望能够从中获取计数并将其添加回初始数据表 db2。然后,当用户选择计数大于 1 的行时,我可以提醒用户。我只想在用户选择更高的文件编号时发出警报,因此我可能需要通过排名来执行此操作,但无论哪种方式,我怎样才能将我拥有的内容添加回原始表格?

标签: c#linqdatatable

解决方案


显然,您设计可以通过 、 等的值来识别测量ToolProduct如果您有两个具有相同 、 等值的项目ToolProduct它们属于同一个测量组,甚至可能是相同的测量。

为了防止我不得不一遍又一遍地说“相同的工具、产品等”,我将这些属性的集合称为MeasurementId. 所以每当我说MeasurementId,我的意思是属性 Tool/Product/Timel/Row

问题描述

如果您有两个相同的测量值MeasurementId,则它们可能是重新测量值。因此,每当操作员选择了其他具有相同 的测量时MeasurementId,您都希望警告操作员,如果操作员选择了最旧的测量,则可能不会。

您的问题似乎类似于在数据库中保留多个版本的内容。如果有人将具有相同“MeasurementId. but with a different文件版本”的新项目添加, it is as if you add a new到您的数据库中。

如果他没有选择最旧的版本,您想警告操作员。

您选择了以下解决方案:

我希望能够从中获取计数并将其添加回初始数据表 db2

与其将计数添加到您的表中,不如考虑添加“先前版本”的 Id,如果没有先前版本,则添加 0。

class Measurement
{
     public int Id {get; set;}
     public int File {get; set;}

     // measurement identification
     public string Tool {get; set;}
     public string Product {get; set;}
     ...

     // you wanted to add a Count, instead add a previous version
     public int PreviousMeasurementId {get; set;}   // 0 if no previous measurement
}

在添加测量之前,检查是否已经有类似的测量:

void AddMeasurement(Measurement measurementToAdd)
{
     var lastMeasurementVersionId = dbContext.Measurements
         .Where( measurement => // select with same measurementId:
             measurement.Tool == measurementToAdd.Tool
             && measurement.Product == measurementToAdd.Product
             && ...)
         // from the remaining versions, keep the one with the highest File:
         .OrderByDescending(measurement => measurement.File)
         // I'm only interested in the Id of this measurement
         .Select(measurement => measurement.Id)
         .FirstOrDefault();

现在,如果已经有类似的测量,lastMeasurementVersionId 是最后一个类似测量的 Id。如果没有,则该值等于 0。

将 lastMeasurementVersionId 分配给 后添加新测量PreviouseMeasurementId

    measurementToAdd.PreviousMeasurementId = lastMeasurementVersionId;
    dbContext.Measurements.Add(measurementToAdd);
    dbContext.SaveChanges();
}

这将如何帮助我解决我的问题?

如果操作员选择 a Measurement,您唯一需要做的就是检查 的值PreviousMeasurementId。如果为零,则操作员选择了第一个测量,如果不是,您可以警告操作员此测量有多个版本。选择的可能是重新测量。

可能的改进:

  • 考虑为您的复合材料添加一个额外的索引MeasurementId。a 的值MeasurementId不会经常变化,但是使用它获取所有测量值的查询MeasurementId要快得多
  • 如果您对所有版本都不感兴趣,而实际上只对第一个版本感兴趣,请不要记住PreviousMeasurementId,而记住FirstMeasurementId.

推荐阅读