2013-05-15 5 views
2

Im пытается удалить строки из DataTable AllItems с строками из DataTables Items; Целью этого является получение предметов от DataTable AllItems, которые не находятся внутри. DataTable ItemsТаблица не имеет первичного ключа C#

Все эти строки, сфабрированные из того же файла Excel, который содержит несколько столбцов и равны.

Я попытался с помощью цикла Еогеаспа:

foreach(DataRow dr in AllItems.Rows) 
{ 
if (Items.Contains(dr)) 
{ 
AllItems.Rows.Remove(dr); 
} 

Но я получаю следующее сообщение об ошибке: Таблица не имеет первичный ключ.

Кто-нибудь знает, как я могу удалить эти строки?

+0

Это [лучший] (http://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx), чтобы использовать верблюд-первый верблюд-футляр для 'variableNames'. –

+0

Голосовать за закрытие (замечено после добавления ответа): http://stackoverflow.com/questions/4415519/best-way-to-remove-duplicate-entries-from-a-data-table - в частности, http://stackoverflow.com/a/15264638/1073107 дает очень сукцинный ответ для удаления повторяющихся строк. – dash

ответ

1

У вас есть несколько вариантов здесь:

1. Добавьте первичный ключ

вы можете добавить primary key to your data table при его создании.

Предполагая, что вы имели столбец «Id», то вы могли бы сделать это следующим образом:

AllItems.PrimaryKey = new DataColumn[] { workTable.Columns["Id"] };} 

Или, за исключением случаев, когда ваш первичный ключ является составным ключом (несколько столбцов):

AllItems.PrimaryKey = new DataColumn[] { 
          workTable.Columns["Id"], 
          workTable.Columns["Name"] };} 

Это позволило бы Содержанию работать правильно.

2. Использование DataView

Вы можете использовать DataView, чтобы отфильтровать определенные строки;

DataView view = new DataView(AllItems); 
DataTable distinctValues = view.ToTable(true, "Column1", "Column2" , ..., "ColumnN"); 

3. Найдите соответствующие строки с помощью Select

Или вы можете полагаться на метод Select, чтобы проверить, если соответствующая строка существует в Items DataTable на основе заявления, что это как SQL WhereClause:

List<DataRow> rowsToRemove = new List<DataRow>(); 

foreach(DataRow allItemRow in AllItems.Rows) 
{ 
    if(Items.Select(String.Format("Id = {0}"), 
      allItemRow.Field<Int32>("Id")).Length == 0) 
    { 
     rowsToRemove.Add(allItemRow); 
    } 
} 

rowsToRemove.ForEach(x => x.Delete()); 

AllItems.AcceptChanges(); 

Примечания, что это важно не удалять строки в то время как вы перебор коллекции Rows в AllItems - вместо этого собирайте эти строки и удалите их потом.

4. Фильтр по пути в

Кроме того, обратите внимание, и я не пробовал, но, в зависимости от того, как вы выбираете строки из Excel, вы можете быть в состоянии использовать SQL Предложение DISTINCT; если вы используете ODBC to load data from Excel, тогда вы можете попробовать фильтровать в источнике.

+0

Thx это помогло мне :) –

0

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

var exceptItems = AllItems.Rows.Cast<DataRow>() 
    .Except(Items.Rows.Cast<DataRow>(), DataRowComparer.Default) 
    .ToList(); 

В качестве альтернативы, если вы хотите продолжать работать с таблицей данных allItems после удаления items строки из него, вы можете попробовать это (при условии, что у вас есть столбец Id в обеих таблицах данных, который однозначно определяет строку в таблице данных):

var exceptItems = AllItems.Rows.Cast<DataRow>() 
    .Select((i, index) => new { id = i["Id"], index }) 
    .Intersect(Items.Rows.Cast<DataRow>() 
     .Select((i, index) => new { id = i["Id"], index })) 
    .ToList(); 

for (int i = exceptItems.Count()-1; i >= 0; i--) 
{ 
    AllItems.Rows.RemoveAt(exceptItems[i].index); 
} 

Вот лучше расположение последнего примера выше:

AllItems.Rows.Cast<DataRow>() 
    .Select((i, index) => new { id = i["Id"], index }) 
    .Intersect(Items.Rows.Cast<DataRow>() 
     .Select((i, index) => new { id = i["Id"], index })) 
    .OrderByDescending(i => i.index) 
    .ToList() 
    .ForEach(i => AllItems.Rows.RemoveAt(i.index)); 
+0

Он не удаляет строки после выделения этого AllItems.Count то же самое –

+0

Вы можете работать с 'exceptItems'. –

+0

Я добавил две альтернативы удаления строк 'Items' из таблицы« AllItems ». Они будут работать только в том случае, если у вас есть общий столбец «ИД», который идентифицирует строки. –

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