Как видно из заголовка, мне нужна пользовательская сортировка для моего DataTable, где я использую индекс DataRow, и результатом должен быть EnumerableRowCollection или OrderedEnumerableRowCollection, потому что я хочу таблицу (порядок по умолчанию) и DataView (настраиваемый порядок).
Порядок, который я хочу: сначала отсортировать по нескольким столбцам (например, имя, фамилия, ...). Затем разделите таблицу на table1 и table2 (только половина таблицы). Затем поочередно выбирайте из первой и второй таблицы. Результат должен быть
строка таблицы1
строка таблицы2
строка таблицы1
исходная таблица не должна быть затронута, и результат должен быть ссылкой на исходную таблицу.
internal static DataView GetSortedView(this DataTable table)
{
return table.GetSortedTable().AsDataView();
}
internal static void OrderedEnumerableRowCollection<DataRow> GetSortedTable(this DataTable table)
{
int half = table.Rows.Count / 2;
//sort columns by name for example
var enumerable = table.AsEnumerable().OrderBy(field => field.Field<string>("Name"), new NaturalStringComparer());
//here is the tricky part
enumerable= enumerable.OrderBy(row =>
{
int myIndex = ?; //I cannot use table.Rows.IndexOf(row) because the order of the current OrderedEnumerableRowCollection should be used and not the default order of the table
bool upperHalf = myIndex > half;
if (upperHalf)
{
myIndex -= half;
}
return new CustomSortItem(myIndex , upperHalf);
}, new CustomSort());
return enumerable;
}
Сначала я попытался добавить новый столбец для индексов, но на самом деле это не работает, потому что, когда я пытаюсь удалить столбец, в конце я получаю исключение из-за отложенной загрузки.
internal static void OrderedEnumerableRowCollection<DataRow> GetSortedTable(this DataTable table)
{
//create another column for an index
string tempSortName = "[TEMP_SORT]";
table.Columns.Add(tempSortName);
//sort columns by Name for example
var enumerable= table.AsEnumerable().OrderBy(field => field.Field<string>("Name"), new NaturalStringComparer());
//set the temporary order (index)
int count = 0;
foreach(DataRow row in enumerable)
{
row[tempSortName] = count++;
}
//here is the tricky part
int half = table.Rows.Count / 2;
enumerable= enumerable.OrderBy(row =>
{
int myIndex = int.parse(row[tempSortName].ToString()); //exception here. column not found
bool upperHalf = myIndex > half;
if (upperHalf)
{
myIndex -= half;
}
return new CustomSortItem(myIndex , upperHalf);
}, new CustomSort());
table.Columns.Remove(tempSortName);
return enumerable;
}
Я также не хочу использовать IEnumerable, потому что когда я создаю DataView, мне нужно создать другую таблицу, чтобы создать ее, а затем ссылка теряется (view.Table - это не оригинальная таблица, а просто копия без ссылки).
IEnumerable<DataRow> enumerable...
enumerable.CopyToDataTable().AsDataView();
// I have to call CopyToDataTable() in order to create a DataView