使用 Distinct() 删除数据库中具有主键的重复行

本文关键字:Distinct 删除 数据库 使用 | 更新日期: 2023-09-27 18:31:50

我的数据库中有一些重复的值,所以我使用 Linq to Entity 使用以下代码删除它们。问题是 RosterSummaryData_Subject_Local 中有一个自动编号的主键,这使行var distinctRows = allRows.Distinct();因此,即使所有行都相同,不同也不起作用,因为 pk 不同。有没有办法在区别上诋毁pk?或者无论如何将其从查询中删除,使其成为非问题。请注意,我希望查询返回我的实体类型的 IQueryable,以便我可以在 enttiy 上使用 RemoveRange() 方法来删除重复项。

var allRows = (from subjLocal in customerContext.RosterSummaryData_Subject_Local
                           select subjLocal);
var distinctRows = allRows.Distinct();
if (allRows.Count() == distinctRows.Count())
{
     return;
}
else
{
     var rowsToDelete = allRows.Where(a => a != distinctRows);
     customerContext.RosterSummaryData_Subject_Local.RemoveRange(rowsToDelete);
}

编辑

意识到要正确返回不同的行,我所要做的就是选择除主键之外的所有项目:

var distinctRows = allRows
                   .Select(a => new {a.fkRosterSetID, a.fkTestInstanceID, a.fkTestTypeID, 
                                      a.fkSchoolYearID, a.fkRosterTypeID, a.fkDistrictID, 
                                      a.fkSchoolID, a.fkGradeID, a.fkDepartmentID, 
                                      a.fkCourseID, a.fkPeriodID, a.fkDemoCommonCodeID, 
                                      a.fkDemoCommonCategoryID, a.fkTest_SubjectID})
                   .Distinct();

问题是我无法使用下面的代码获取重复的行,因为 ! 运算符不适用于匿名类型(变量 distinctRows 是匿名类型,因为我没有选择所有列):

var rowsToDelete = allRows.Where(a => a != distinctRows);

有什么帮助吗?

使用 Distinct() 删除数据库中具有主键的重复行

你可以试试这个:

var allRows = (from subjLocal in customerContext.RosterSummaryData_Subject_Local
                       select subjLocal).ToList();
var distinctRows = allRows.Distinct().ToList();

由于您将处理列表对象,因此在原始 else 语句中您可以这样做:

else
{
     var rowsToDelete = allRows.Where(a => !distinctRows.Contains(a));
     customerContext.RosterSummaryData_Subject_Local.RemoveRange(rowsToDelete);
}

为了处理数据库中 Distinct() 和自动编号 ID 的问题,我能想到两种解决方案。

一个是你可以引入 MoreLinq 库,它是一个 Nuget 包。 然后你可以使用 MoreLinq 方法 DistinctBy():

allRows.DistinctBy(a => a.SomePropertyToUse);

或者另一种途径是使用IEqualityComparer与常规.Distinct() Linq Method.您可以查看此 SO 问题,了解有关使用 IEqualityComparer 的更多信息。Distinct() 方法。 使用 IEqualityComparer 进行区分

也许您需要检查customerContext.RosterSummaryData_Subject_Local中的每个字段以查看哪个字段不同