Сортировка System.Data.DataTable с несколькими критериями сортировки - PullRequest
1 голос
/ 02 августа 2020

У меня есть это System.Data.DataTable:

DataTable dt = new DataTable();
dt.Columns.Add("Sector", typeof(string));
dt.Columns.Add("BBG IPC", typeof(double));
dt.Columns.Add("Analyst", typeof(string));
dt.Columns.Add("Issuer Group", typeof(string));
dt.Columns.Add("Seniority", typeof(string));
dt.Columns.Add("Mkt Value", typeof(double));
dt.Columns.Add("Nom Value", typeof(double));
dt.Columns.Add("Issue Group Rating", typeof(string));
dt.Columns.Add("Current SBR", typeof(string));
dt.Columns.Add("Notches", typeof(int));
dt.Columns.Add("Forward SBR", typeof(string));
dt.Columns.Add("Probability of Downgrade", typeof(string));
dt.Columns.Add("Risk Category", typeof(string));
dt.Columns.Add("Comment", typeof(string));
dt.Columns.Add("Restricted Message", typeof(string));


dt.Rows.Add(new object[] { "Agencies", 180969, "MUSTO", "Caisse des Depots", "Senior", 10114481, 1000000, "AA", "BB",-1, "YY", "Hight", "R1", "Comment", "gvbhjnnijnibj" });
dt.Rows.Add(new object[] { "Agencies", 180969, "MUSTO", "Caisse des Depots", "Senior", 10114481, 1000000, "AA", "CC",2, "II", "Low", "R2", "Bergtrgrt", "Other" });
dt.Rows.Add(new object[] { "Agencies", 180969, "MUSTO", "Caisse des Depots", "Senior", 10114481, 1000000, "AA", "EE",3, "LL", "Mid", "R1", "vggvbhjjnnjoioion", "ggvbhibniujbuhvg uvvugvghV" });
dt.Rows.Add(new object[] { "Consumer", 180969, "MUSTO", "Caisse des Depots", "Senior", 10114481, 1000000, "AA", "OO",-1, "SS", "Higth", "R3", "vgvgyhvgvjhbkj", "bibhjbhjbjhb  ubuyhbuyhb hbuhbuhbhb" });
dt.Rows.Add(new object[] { "Energy", 180969, "MUSTO", "Caisse des Depots", "Senior", 10114481, 1000000, "AA", "PP",-2, "QQ","Higth", "R1", "ertyuiop", "tfcgvhb Uvugvugvuhvh" });
dt.Rows.Add(new object[] { "Energy", 180969, "MUSTO", "Caisse des Depots", "Senior", 10114481, 1000000, "AA", "GG",-3, "FF", "Low", "R2", "gvgvgvvgfccfdxdxrtf xrtfvgh tdctfgv trcfygvh tcfyghv b ygvhb ", "ygvgubiujb" });

Мне нужно отсортировать таблицу на основе следующих правил:

1-й уровень: сектор в алфавитном порядке c порядок.

2-й уровень: вероятность понижения в следующем порядке: высокий, средний, низкий

3-й уровень: группа эмитентов в алфавитном порядке c порядок

введите описание изображения здесь

Я пробовал что-то вроде этого dt.DefaultView.Sort("Sector", "Probability of Downgrade", "Issuer Group");, но не работает. Как мне это сделать? Спасибо!

Ответы [ 2 ]

3 голосов
/ 02 августа 2020

Синтаксис свойства DataView.Sort очень похож на синтаксис, используемый в SQL Server.

В вашем примере вы можете использовать эту строку:

dt.DefaultView.Sort = "Sector ASC, [Probability of Downgrade] ASC, [Issuer Group] ASC";

.. а затем просто введите dt.DefaultView в своем коде.

Но у вас, вероятно, возникнет проблема, потому что сортировка по возрастанию («Высокая», «Средняя», «Низкая») вернет их как «Высокий», «Низкий», «Средний». Поскольку это строки, он будет делать это в алфавитном порядке.

Простейшим решением было бы использовать числовое c представление вероятности, если оно есть в исходной базе данных, и отображать High / Mid / Низкий, но не сортировать по ним.

Вот обходной путь LINQ, если единственный вариант данных, который у вас есть, - это строка вероятности:

// Make a dictionary to map your probability strings to integers.
var probLookup = new Dictionary<string, int>();
probLookup["High"] = 3;
probLookup["Mid"] = 2;
probLookup["Low"] = 1; 

// Convert your DataTable into an array of a new type, that has the DataRow
// plus the three things you need to sort by, as separate properties.
var temp = dt.Select().Select(row => new() {   
                                   Row = row,
                                   Sector = row["Sector"],
                                   // Map the downgrade prob. to an integer.
                                   DowngradeProb = probLookup[(string) row["Probability of Downgrade"]],
                                   IssuerGroup = row["Issuer Group"]
                                 });

// Now, sort it by the 3 properties we created.
var temp2 = temp
           .OrderBy(a => a.Sector)
           .ThenByDesc(a => a.DowngradeProb)
           .ThenBy(a => a.IssuerGroup);

// Now, fish out the Row again.
var temp3 = temp2.Select(a => a.Row).ToArray();

ВАЖНЫЙ ОТКАЗ: LINQ был создан по памяти: я этого не гарантирую!

2 голосов
/ 02 августа 2020

Попробуйте выполнить следующий запрос:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication11
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> probabilityStr = new List<string>() { "Hight", "Mid", "Low" };

            DataTable dt = new DataTable();
            dt.Columns.Add("Sector", typeof(string));  //1
            dt.Columns.Add("BBG IPC", typeof(double));
            dt.Columns.Add("Analyst", typeof(string));
            dt.Columns.Add("Issuer Group", typeof(string));  //3
            dt.Columns.Add("Seniority", typeof(string));
            dt.Columns.Add("Mkt Value", typeof(double));
            dt.Columns.Add("Nom Value", typeof(double));
            dt.Columns.Add("Issue Group Rating", typeof(string));
            dt.Columns.Add("Current SBR", typeof(string));
            dt.Columns.Add("Notches", typeof(int));
            dt.Columns.Add("Forward SBR", typeof(string));
            dt.Columns.Add("Probability of Downgrade", typeof(string));  //2
            dt.Columns.Add("Risk Category", typeof(string));
            dt.Columns.Add("Comment", typeof(string));
            dt.Columns.Add("Restricted Message", typeof(string));


            dt.Rows.Add(new object[] { "Agencies", 180969, "MUSTO", "Caisse des Depots", "Senior", 10114481, 1000000, "AA", "BB", -1, "YY", "Hight", "R1", "Comment", "gvbhjnnijnibj" });
            dt.Rows.Add(new object[] { "Agencies", 180969, "MUSTO", "Caisse des Depots", "Senior", 10114481, 1000000, "AA", "CC", 2, "II", "Low", "R2", "Bergtrgrt", "Other" });
            dt.Rows.Add(new object[] { "Agencies", 180969, "MUSTO", "Caisse des Depots", "Senior", 10114481, 1000000, "AA", "EE", 3, "LL", "Mid", "R1", "vggvbhjjnnjoioion", "ggvbhibniujbuhvg uvvugvghV" });
            dt.Rows.Add(new object[] { "Consumer", 180969, "MUSTO", "Caisse des Depots", "Senior", 10114481, 1000000, "AA", "OO", -1, "SS", "Higth", "R3", "vgvgyhvgvjhbkj", "bibhjbhjbjhb  ubuyhbuyhb hbuhbuhbhb" });
            dt.Rows.Add(new object[] { "Energy", 180969, "MUSTO", "Caisse des Depots", "Senior", 10114481, 1000000, "AA", "PP", -2, "QQ", "Higth", "R1", "ertyuiop", "tfcgvhb Uvugvugvuhvh" });
            dt.Rows.Add(new object[] { "Energy", 180969, "MUSTO", "Caisse des Depots", "Senior", 10114481, 1000000, "AA", "GG", -3, "FF", "Low", "R2", "gvgvgvvgfccfdxdxrtf xrtfvgh tdctfgv trcfygvh tcfyghv b ygvhb ", "ygvgubiujb" });


            DataTable dt2 = dt.Clone();

            var sectors = dt.AsEnumerable()
                .OrderBy(x => x.Field<string>("Sector"))
                .ThenBy(x => probabilityStr.IndexOf(x.Field<string>("Probability of Downgrade")))
                .ThenBy(x => x.Field<string>("Issuer Group"))
                .GroupBy(x => x.Field<string>("Sector"))
                .ToList();

            for (int si = 0; si < sectors.Count(); si++)
            {
                var probabilities = sectors[si].GroupBy(x => x.Field<string>("Probability of Downgrade")).ToList();
                for (int pi = 0; pi < probabilities.Count(); pi++)
                {
                    var groups = probabilities[pi].GroupBy(x => x.Field<string>("Issuer Group")).ToList();
                    for (int gr = 0; gr < groups.Count(); gr++)
                    {
                        for (int r = 0; r < groups[gr].Count(); r++)
                        {
                            DataRow row = dt2.Rows.Add();
                            for (int i = 0; i < dt2.Columns.Count; i++)
                            {
                                switch (dt2.Columns[i].ColumnName)
                                {
                                    case "Sector" :
                                        if (pi == 0)
                                        {
                                            row["Sector"] = sectors[si].Key;
                                        }
                                        else
                                        {
                                            row["Sector"] = DBNull.Value;
                                        }
                                        break;

                                    case "Probability of Downgrade" :
                                        if (gr == 0)
                                        {
                                            row["Probability of Downgrade"] = probabilities[pi].Key;
                                        }
                                        else
                                        {
                                            row["Probability of Downgrade"] = DBNull.Value;
                                        }
                                        break;

                                    case "Issuer Group" :
                                        if (r == 0)
                                        {
                                            row["Issuer Group"] = groups[gr].Key;
                                        }
                                        else
                                        {
                                            row["Issuer Group"] = DBNull.Value;
                                        }
                                        break;

                                    default :
                                        row[i] = groups[r].First()[dt2.Columns[i].ColumnName];
                                        break;
                                }

                            }
                        }
                    }
                }
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...