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

时间:2014-11-24 00:14:41

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

我的数据库中有一些重复的值,所以我使用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();

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

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

任何帮助?

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

你可以试试这个:

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);

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