c# - 使用 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 的行时,我可以提醒用户。我只想在用户选择更高的文件编号时发出警报,因此我可能需要通过排名来执行此操作,但无论哪种方式,我怎样才能将我拥有的内容添加回原始表格?
解决方案
显然,您设计可以通过 、 等的值来识别测量Tool
:Product
如果您有两个具有相同 、 等值的项目Tool
,Product
它们属于同一个测量组,甚至可能是相同的测量。
为了防止我不得不一遍又一遍地说“相同的工具、产品等”,我将这些属性的集合称为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
.