pradeepbliss Ответов: 4

Удаление повторяющихся строк из Таблицы данных на основе нескольких столбцов


У меня есть таблица данных, которая содержит много повторяющихся строк, мне нужно отфильтровать эти строки из таблицы данных на основе нескольких столбцов, чтобы получить отдельные строки в результирующей таблице данных....
Barcode Itemid PacktypeId

1      100      1

1      100      2

1      100      3

1      100      1

1      100      3

нужны только строки, которые содержат packtypeid 1,2,3 оставшиеся 4-я и 5-я строки должны быть удалены

Я пробовал использовать два метода, но ни один из них не сработал для лучшего результата

Таблица данных содержит более 10 столбцов, но уникальный столбец "штрих-код", "идентификатор элемента", "PackTypeID"

Способ-1:

dt_Barcode = dt_Barcode.DefaultView.ToTable(true, "Barcode", "ItemID", "PackTypeID");

Вышеописанный метод фильтрует строки, но он возвращает столбцы только 3 значения столбцов, мне нужны целые 10 значений столбцов.

Способ-2:
List<string> keyColumns = new List<string>();
keyColumns.Add("Barcode");
keyColumns.Add("ItemID");
keyColumns.Add("PackTypeID");   
RemoveDuplicates(DataTable table, List<string> keyColumns)
{
	var uniqueness = new HashSet<string>();
	StringBuilder sb = new StringBuilder();
	int rowIndex = 0;
	DataRow row;
	DataRowCollection rows = table.Rows;             
	int i = rows.Count;
	while (rowIndex < i)
	{
	row = rows[rowIndex];
	sb.Length = 0;
	foreach (string colname in keyColumns)
	{
		sb.Append(row[colname]);
		sb.Append("|");
	}
	
	if (uniqueness.Contains(sb.ToString()))
	{
		rows.Remove(row);
	}
	else
	{
		uniqueness.Add(sb.ToString());
		rowIndex++;
	}
}

Вышеприведенный метод возвращает исключение типа нет строк в позиции 5

4 Ответов

Рейтинг:
31

DamithSL

попробуйте с LINQ

dt_Barcode = dt_Barcode.AsEnumerable()
            .GroupBy(r => new { Itemid = r.Field<int>("Itemid"), PacktypeId = r.Field<int>("PacktypeId")})
            .Select(g => g.First())
            .CopyToDataTable();


Пример Тестового Кода:
void Main()
{
    DataTable dt_Barcode =GetTable();
	dt_Barcode = dt_Barcode.AsEnumerable()
            .GroupBy(r => new { Itemid = r.Field<int>("Itemid"), PacktypeId = r.Field<int>("PacktypeId")})
            .Select(g => g.First())
            .CopyToDataTable();
}

DataTable GetTable()
{
	DataTable table = new DataTable();
	table.Columns.Add("Barcode", typeof(int));
	table.Columns.Add("Itemid", typeof(int));
	table.Columns.Add("PacktypeId", typeof(int));
	table.Rows.Add(1,100,1);
	table.Rows.Add(1,100,2);
	table.Rows.Add(1,100,3);
	table.Rows.Add(1,100,1);
	table.Rows.Add(1,100,3);
	return table;
}


pradeepbliss

Привет DamithSL частично u r правильно, но мне нужно передать оба packtypeid и itemid одновременно через linq, как я могу выполнить оба в предложении where...

DamithSL

проверьте мой обновленный ответ

pradeepbliss

Привет, я получаю неправильный синтаксис рядом, (недопустимый термин выражения ,)

DamithSL

О, извините, нужно использовать новое ключевое слово

pradeepbliss

привет, мне очень жаль, что я новичок в linq, я получаю синтаксическую ошибку->недопустимый анонимный член-Декларатор типа........

DamithSL

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

pradeepbliss

проверено с помощью последнего кода, но получает исключение времени выполнения->указанное приведение недопустимо.но работает для одного параметра....

DamithSL

есть ли у вас нулевые значения в этих столбцах или у вас есть какой-либо текст или символы с любым из этих значений столбцов?
Я использовал r.Field<int> , предполагая, что у вас есть целочисленные данные в ваших столбцах, если у вас есть текстовые поля, вам лучше изменить их на r.Field<string>

pradeepbliss

вау, превосходно, это прекрасно работает...отличная работа, чувак

Manas Bhardwaj

+5!

DamithSL

спасибо тебе, Манас

Рейтинг:
21

Rajesh Varma Buddaraju

Пример кода для вашей проблемы.
Список<предметы&ГТ; arritems = новый список<предметы&ГТ;();
items item = новые элементы();
элементы элемент1 = новинки();
детали место № 2 = новинки();
items item3 = новые элементы();
элементы item4 = новинки();
товар.штрих-код = 1;
item. itemid = 100;
item.packtypeid = 1;

элемент1.штрих-код = 1;
элемент1.идентификатор Itemid = 100;
item1.packtypeid = 2;

место № 2.штрих-код = 1;
место № 2.идентификатор Itemid = 100;
место № 2.packtypeid = 3;

item3.штрих-код = 1;
item3.идентификатор Itemid = 100;
item3.packtypeid = 1;

item4.штрих-код = 1;
item4.идентификатор Itemid = 100;
item4.packtypeid = 3;


арритемы.Добавить элемент);
арритемы.Добавить(item1);
арритемы.Добавить(item2);
арритемы.Добавить(item3);
арритемы.Добавить(item4);

var distinctList = arritems.Выберите(x => new{x.itemid , x.packtypeid}).Отчетливый().Список();


public class items
    {
        public int barcode;
        public int itemid;
        public int packtypeid;
    }


sudhakarkoganti

У меня есть похожая проблема ... это работает для меня.

pradeepbliss

основываясь на производительности и оптимизации кода, что лучше либо linq, либо datatable select........

Rajesh Varma Buddaraju

Там нет большой разницы в производительности на обоих. Вы можете пойти с linq.

Рейтинг:
0

subho100

public void RemoveDuplicatesFromDataTable(ref DataTable table, List<string> keyColumns)
        {

            Dictionary<string, string> uniquenessDict = new Dictionary<string, string>(table.Rows.Count);
            StringBuilder stringBuilder = null;
            int rowIndex = 0;
            DataRow row;
            DataRowCollection rows = table.Rows;
            string error = string.Empty;

            try
            {
                while (rowIndex < rows.Count)
                {

                    row = rows[rowIndex];

                    stringBuilder = new StringBuilder();

                    foreach (string colname in keyColumns)
                    {
                        try
                        {
                            if (row[colname].ToString() != string.Empty)
                            {
                                stringBuilder.Append(((string)row[colname]));
                            }
                            else
                            {
                                //If it comes here, means one of the keys are blank
                                error += "One of the key values is blank.";
                            }
                        }
                        catch (Exception ss)
                        {
                            error += "Error " + ss.Message + ".";
                        }
                    }

                    if (uniquenessDict.ContainsKey(stringBuilder.ToString()))
                    {
                        rows.Remove(row);
                    }
                    else
                    {
                        uniquenessDict.Add(stringBuilder.ToString().Replace(",", ""), string.Empty);
                        rowIndex++;
                    }

                }
            }
            catch (Exception ex)
            {
                error = "Failed - " + ex.Message;
            }

            if(error != string.Empty)
                Show(error);
        }


Richard Deeming

Необъяснимый дамп кода не является "решением" этого уже решенного вопроса.

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