0

I have some duplicate values in my database so I am using Linq to Entity to remove them with the code below. The problem is that there is an autonumber primary key in RosterSummaryData_Subject_Local, which invalidates the line var distinctRows = allRows.Distinct(); So, even if all the rows are the same, distinct won't work because the pk is different. Is there anyway to discredit the pk in the distinct? Or anyway to remove it from the query so it becomes a non issue. Just to note I want the query to return an IQueryable of my entity type so I can use the RemoveRange() method on the enttiy to remove the duplicates.

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

EDIT

I realized that to properly bring back distinct rows, all I have to do is select all the items except primary key:

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

The problem is that I cannot fetch the duplicate rows with the code below because the ! operator does not work with anonymous types(the variable distinctRows is an anonymous type because I didn't select all the columns):

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

Any help?

frontin
  • 733
  • 2
  • 12
  • 28

2 Answers2

0

maybe you need to check for each one of the fields in your customerContext.RosterSummaryData_Subject_Local to see which one is different

Jack1987
  • 727
  • 1
  • 14
  • 26
0

you can try this:

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

var distinctRows = allRows.Distinct().ToList();

Since you will be dealing with list objects, then in your original else statement you can do this:

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

To handle your issue with Distinct() and the autonumberID in the database, there are two solutions I can think of.

One is you can bring in the MoreLinq library, it's a Nuget package. then you can use the MoreLinq method DistinctBy():

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

Or the other route would be to use an IEqualityComparer with the regular .Distinct() Linq Method. You can check out this SO question for more info on using an IEqualityComparer in the .Distinct() method. using distinct with IEqualityComparer

Community
  • 1
  • 1
Russell Jonakin
  • 1,716
  • 17
  • 18