8
votes

Création de manière dynamique GridView

Je souhaite créer un gridview qui affiche des enregistrements pour les fichiers PDF. Ces enregistrements peuvent avoir des méta-données attachées à caractère personnalisable par l'utilisateur, afin qu'ils puissent créer leurs propres colonnes et entrer leurs propres informations là-bas. Je veux ensuite qu'il soit affiché dans une grilleille, ils peuvent donc commander chaque colonne et l'ordre de colonne si l'ordre de colonne est -1, il ne s'affichera pas dans la grille.

Par exemple il y a une table statique p> xxx pré>

Il existe une autre table que les utilisateurs peuvent créer leurs propres colonnes pour p> xxx pré>

et la table pour contenir les valeurs p>

private DataTable CreateColumns()
{
   var columns =  select * from MetaDataColumns 
                  where userid = UserId;

   DataTable dt = new DataTable();

   foreach (column in columns)
   {
       dt.Columns.Add(new DataColumn(column[keyName], typeof(string));  //assumes all string
   }

 return dt
}

private void PopulateDG(DataGrid dg)
{
    var documents = select * from DocumentsTable
                     where userid=UserId;

    foreach (document in documents)
    {            
        var columnValues = select * from MetaDatavalues 
                           documentID == document.id;

        DataRow dr = dg.NewRow();
        dr[columnValues.KeyName] = columnValues.value;

    }

 }

 private void LoadGV()
 {  
   DataGrid dg = CreateColumns();
   PopulateDG(dg);
   GridView.datasource = dg;
   GridView.DataBind();
  }


0 commentaires

3 Réponses :


1
votes

voulez-vous dire xxx

et créer une classe dans le code derrière comme xxx


0 commentaires

1
votes

Je vois certainement un problème avec votre approche pseudo-code où chaque ligne d'une donnée représente une requête distincte. Lorsque vous avez 1 000 lignes de données, vous finiriez par avoir 1 000+ requêtes frapper la base de données, votre page serait extrêmement lente.

Vous pouvez au moins combiner deux des requêtes SQL comme une étape immédiate pour améliorer la situation, telle AS: P>

private void PopulateDG(DataGrid dg)
{
    var columns = SELECT columnKey FROM MetaDataColumns
            WHERE userid = UserId;

    // pseudo code, join column keys into a comma delimited string
    string columnFields = string.Join(",", columns);

    string getValueSql = string.Format("SELECT {0} FROM MetaDataValues
            WHERE documentid IN (SELECT id FROM DocumentsTable WHERE userid = UserId)", columnFields);

    var values = ExecuteSql(getValueSql);


0 commentaires

2
votes

Votre problème est principalement dû à la conception em> de la base de données. Vous devez ajouter dynamiquement des colonnes parce que vous avez traduit ce serait une colonne ( en 3FN ) à une ligne dans vos tables. Évidemment, ceci est parce que vous permettez aux utilisateurs d'ajouter leurs propres colonnes - mes frissonne esprit, mais c'est la façon dont le application fonctionne: -.)

En raison de la structure de MetaDataColumns code> Je vais supposer qu'un utilisateur a la possibilité de définir un ensemble de noms de colonnes qu'ils peuvent ensuite choisir d'appliquer à un document individuel comme ils le souhaitent. p>

Je pense que le problème est que d'essayer de tout Normaliser correctement, en une base de données complètement de normalisée, vous avez réussi à vous causer beaucoup de tracas. Ma solution serait de denormalise votre table MetaDataValues ​​ code>. Vous ne mentionnez pas ce que vous utilisez SGBDR MySQL, mais a une limite difficile de 4096 colonnes ou 65K octets. La limite dans Oracle est 1000 et 1024 dans SQL Server. p>

Si vous modifiez la structure de MetaDataValues ​​ code> à vous suiviez devriez pouvoir adapter au moins em> 332 ensembles d'informations là-dedans. Ce serait séparément unique sur UserID code>, DocumentID code> vous pouvez donc, théoriquement, retirer la clé de substitution ID code>. P>

select d.*, m.*
  from DocumentsTable d
  join MetaDataValues m
    on d.ID = m.DocumentID
   and d.UserID = m.UserID
 where d.UserId = ?


6 commentaires

Mon design original était juste d'avoir 10 colonnes que les utilisateurs pourraient renommer. De toute évidence, je pourrais étendre cela à autant de colonnes que nécessaire et avoir une limite maximale ...


Avant de descendre de cette route. Il n'y a pas une façon d'utiliser Pivot pour seulement utiliser 1 (ou 2 pour obtenir les noms de colonne).


Aussi avec cette idée, quel est le point de la métadonnable. Je ne voudrais que mettre des yeux sur Keynamen, Ordern, Valuen dans la table de documents? La seule raison pour laquelle les 2 autres tables étaient donc pour pouvoir ajouter de manière dynamique des colonnes.


En fait 2 tables. Les valeurs dans la table de documents et le nom de clé et la commande.


Sur pivot, je ne connais aucun dB où vous pouvez nommer de manière dynamique une colonne. Oui, vous pouvez le réduire à deux. Je suis alors séparé parce que je ne savais pas à quel point ce serait une grande entreprise. Ce sera une douleur douleur de mettre à jour les mots-clés, mais si vous n'avez que 10 colonnes, cela devrait être plus facile.


Je choisis cette réponse parce que c'est la façon dont j'ai décidé d'y aller. Au lieu d'avoir des colonnes dynamiques, je viens de faire une quantité maximale de colonnes que l'utilisateur peut renommer et réorganiser