Question

J'ai des données provenant de la base de données sous la forme d'un DataSet.Je l'ai ensuite défini comme DataSource d'un contrôle de réseau avant d'effectuer un DataBind().Je veux trier le DataSet/DataTable sur une colonne.La colonne est trop complexe à trier dans la base de données mais j'espérais pouvoir la trier comme je trierais une liste générique, c'est-à-direen utilisant un délégataire.

Est-ce possible ou dois-je le transférer vers une autre structure de données ?

Modifier Je n'arrive pas à faire fonctionner aucune de ces réponses pour moi, je pense parce que j'utilise .Net 2.0.

Était-ce utile?

La solution

En raison du fonctionnement du tri DataTable (et DataView), vous ne pouvez pas utiliser directement l'approche par délégué. Une solution consiste à ajouter une colonne à la table de données qui représente l'ordre et à définir la valeur (par ligne) en fonction de la séquence souhaitée. Vous pouvez ensuite ajouter un tri à la vue de cette nouvelle colonne. Par exemple (en utilisant LINQ pour faire le tri, juste pour être bref):

var sorted = table.Rows.Cast<DataRow>().OrderBy(row => your code);
int sequence = 0;
foreach(var row in sorted)
{
    row["sequence"] = sequence++;
}

(si vous avez un ensemble de données typé, alors je ne pense pas que vous ayez besoin de l'étape Cast, sinon vous utiliseriez votre sous-classe DataRow dactylographiée)

[modifier pour inclure la version 2.0]

Dans la version 2.0 (c’est-à-dire sans LINQ, etc.), vous pouvez utiliser un List<T> pour effectuer le tri - un peu plus long, mais:

        List<DataRow> sorted = new List<DataRow>();
        foreach(DataRow row in table.Rows)
        {
            sorted.Add(row);
        }
        sorted.Sort(delegate(DataRow x, DataRow y) { your code });
        int sequence = 0;
        foreach(DataRow row in sorted)
        {
            row["sequence"] = sequence++;
        }

(encore une fois, remplacez DataRow si vous utilisez un ensemble de données typé)

Autres conseils

Je pense que DataView.Sort la propriété aiderait. Vous pouvez y accéder via DataTable.DefaultView . .

Si cela ne vous dérange pas de perdre la pagination / le tri sur le contrôle, vous pouvez utiliser quelque chose comme:

var dt = new DataTable();
gvWhatever.DataSource = dt.Select().ToList().Sort();

Et ce tri prendra IComparables, etc. en fonction des surcharges afin que vous puissiez trier comme vous le souhaitez.

protected void grdResult_Sorting(object sender, GridViewSortEventArgs e)
    {
        DataTable dt = ((DataTable)Session["myDatatable"]);
        grdResult.DataSource = dt;
        DataTable dataTable = grdResult.DataSource as DataTable;

    //Code added to fix issue with sorting for Date datatype fields
    if (dataTable != null)
    {   

        DataView dataView = new DataView(dataTable);
        for (int i = 0; i < dataView.Table.Rows.Count; i++)
        {
            try
            {
                dataView.Table.Rows[i]["RESP_DUE_DT"] = common.FormatDateWithYYYYMMDD(Convert.ToDateTime(dataView.Table.Rows[i]["RESP_DUE_DT"]));
                dataView.Table.Rows[i]["RECD_DT"] = common.FormatDateWithYYYYMMDD(Convert.ToDateTime(dataView.Table.Rows[i]["RECD_DT"]));
            }
            catch (Exception ex)
            {

            }
        }

        dataView.Sort = "[" + e.SortExpression + "]" + " " + GetSortDirection(e.SortExpression);

        for (int i = 0; i < dataView.Table.Rows.Count; i++)
        {
            try
            {
                dataView.AllowEdit = true;
                dataView[i].BeginEdit();
                dataView[i]["RESP_DUE_DT"] = common.FormatDateFromStringYYYYMMDD(dataView[i]["RESP_DUE_DT"].ToString());
                dataView[i]["RECD_DT"] = common.FormatDateFromStringYYYYMMDD(dataView[i]["RECD_DT"].ToString());
            }
            catch (Exception ex)
            {

            }
        }
        //End code added to fix the issue with sorting for Date data type fields


        grdResult.DataSource = dataView;
        grdResult.DataBind();


    }
}

Vous pouvez trier la base de données en mémoire, mais je ne sais pas ce que serait "trop ​​complexe pour trier dans la base de données".Si j'étais vous, j'essaierais de le trier dans la base de données, d'utiliser des vues, des index de redondance, des instructions SQL complexes, cela sera probablement plus rapide que de trier un grand ensemble de données en mémoire, avec l'avantage supplémentaire de conserver le tri pour les autres. type de clients (par ex.Services Web, etc.)

Pourquoi la colonne est-elle complexe à trier dans la base de données ? Cela suppose que la complexité du tri sera la même dans la base de données ou dans le framework, à moins qu'il ne s'agisse bien d'une colonne calculée, et même dans ce cas, je suppose que le tri dans la base de données est encore plus rapide.

Cependant, comme John l'a dit, vous pouvez modifier le tri au niveau du formulaire via la propriété DataView.Sort. Je recommanderais de le faire si cela prend trop de temps, et dans ce cas, il serait utile de mettre en cache les résultats.

Vous pouvez le faire en

myTableName.DefaultView.Sort = "MyFieldName DESC";
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top