2014-11-24 2 views
0

У меня есть несколько повторяющихся значений в моей базе данных, поэтому я использую Linq для Entity, чтобы удалить их с помощью кода ниже. Проблема заключается в том, что в RosterSummaryData_Subject_Local есть первичный ключ autonumber, что делает недействительной строку var distinctRows = allRows.Distinct(); Итак, даже если все строки одинаковы, разные не будут работать, потому что pk отличается. Есть ли способ дискредитировать pk в отдельности? Или в любом случае удалить его из запроса, чтобы он стал проблемой. Просто хочу отметить, что я хочу, чтобы запрос возвращал IQueryable моего типа сущности, поэтому я могу использовать метод RemoveRange() для enttiy для удаления дубликатов.Удаление повторяющихся строк в базе данных с использованием первичного ключа с помощью функции Distinct()

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

я понял, что правильно вернуть отдельные строки, все, что нужно сделать, это выбрать все элементы, кроме первичного ключа:

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

Любая помощь?

+0

По какой-либо причине вам нужно написать это в LINQ? Очень просто сделать прямо в SQL. – dbugger

+0

@dbugger и этот проспект должен появляться несколько раз в моей программе. Могу ли я использовать немного общего ADO.NET для его выполнения? – frontin

+0

Да. Строка SQL. cmd.Execute, пойдите о своем дне. Нет необходимости бороться с EF. – dbugger

ответ

0

вы можете попробовать это:

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

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

Поскольку вы будете иметь дело с список объектов , то в своем первоначальном заявлении еще вы можете сделать это:

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

Чтобы обработать проблему с Distinct() и autonumberID в базе данных, есть два решения, о которых я могу думать.

Один из них вы можете принести в библиотеку MoreLinq, это пакет Nuget. то вы можете использовать метод DistinctBy MoreLinq():

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

Или другой маршрут будет использовать IEqualityComparer с регулярным .distinct() Linq метод. Вы можете проверить этот вопрос SO для получения дополнительной информации об использовании IEqualityComparer в методе .Distinct(). using distinct with IEqualityComparer

0

может быть, вам нужно проверить для каждого из полей в вашем customerContext.RosterSummaryData_Subject_Local, чтобы увидеть, какая из них отличается

Смежные вопросы