【问题标题】:Removing duplicate rows in database with primary key using Distinct()使用 Distinct() 删除数据库中具有主键的重复行
【发布时间】:2014-11-24 12:40:47
【问题描述】:

我的数据库中有一些重复的值,所以我使用 Linq to Entity 通过下面的代码删除它们。问题是RosterSummaryData_Subject_Local 中有一个自动编号主键,这会使var distinctRows = allRows.Distinct(); 行无效 因此,即使所有行都相同, distinct 也不起作用,因为 pk 不同。无论如何,有没有诋毁不同的pk?或者无论如何要从查询中删除它,这样它就不会成为问题。请注意,我希望查询返回我的实体类型的 IQueryable,以便我可以在实体上使用 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);

有什么帮助吗?

【问题讨论】:

  • 有什么理由需要在 LINQ 中编写这个?在直接 SQL 中执行非常简单。
  • @dbugger 这个过程需要在我的程序中多次发生。我可以使用一些通用的 ADO.NET 来完成它吗?
  • 是的。 SQL 字符串。 cmd.Execute,开始你的一天。无需与 EF 抗争。

标签: c# sql-server linq entity-framework


【解决方案1】:

你可以试试这个:

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() 和数据库中的 autonumberID 的问题,我可以想到两种解决方案。

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

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

或者另一种方法是使用带有常规 .Distinct() Linq 方法的 IEqualityComparer。您可以查看这个 SO question 以获取有关在 .Distinct() 方法中使用 IEqualityComparer 的更多信息。 using distinct with IEqualityComparer

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-02
      • 1970-01-01
      • 2014-07-12
      • 2017-02-12
      • 1970-01-01
      相关资源
      最近更新 更多