2009-09-23 7 views
0

J'espère qu'il y a une réponse simple à celle-ci que j'ai manqué dans les heures de googling ...Datagridview avec EntitySet trié <T>? (.NET 3.5)

J'ai un DataGridView qui doit afficher et ajouter/supprimer/éditer des enregistrements d'un base de données. J'utilise Entity Framework, donc les enregistrements sont initialement EntitySet.

  • Tentative Un

BindingSource dispose d'installations pour le tri, mais oh ... ils ne semblent pas réellement disponibles si votre DataSource est un EntitySet.

  • Tentative Deux

Essayez et mettre en œuvre le tri personnalisé sur la grille, mais oh ... le tri sur mesure pas autorisée si la grille est databound.

  • Tentative Trois

peform une requête Linq sur mes données et utiliser la fonction de commande là-bas. Cela fonctionne pour obtenir mes données ordonnées, mais oh ... il a changé AllowNew à faux. Je peux le forcer à revenir, mais les enregistrements ajoutés à DataGridView ne sont pas ajoutés à mon EntitySet (même si bizarrement, les mises à jour sont reflétées).

  • Tentative Quatre

Comme par # 3, mais maintenant je gérer l'événement AddingNew pour BindingSource et créer explicitement mon objet et l'ajouter à la EntitySet. Cela fonctionne alors SAUF que si l'utilisateur entre la nouvelle ligne d'entrée au bas de la grille, j'obtiens une rangée pleine de valeurs par défaut ajoutées à ma base de données. Si l'utilisateur continue d'entrer dans la ligne, j'obtiens beaucoup de lignes. Donc ce n'est pas bon non plus.

Il doit y avoir un moyen de le faire - sûrement pour afficher certains enregistrements de base de données dans une grille et permettre l'édition complète est la plus élémentaire des exigences (et il est peu utile d'afficher les lignes dans un ordre aléatoire).

Toute aide les plus reçus avec reconnaissance ...

Répondre

0

Je voudrais encore accueillir des conseils sur la meilleure façon de le faire, mais ce qui suit semble fonctionner pour moi.

Je crée un dérivé de BindingList pour envelopper mes enregistrements renvoyés par LINQ, puis transmettre ceux ObjectContext et EntityCollection. Il remplace les AddNewCore et CancelNew pour placer des objets dans la base de données ainsi que BindingList et semble persister les changements sans les lignes vides non désirées si vous déplacez le focus dans la rangée du bas mais n'écrivez rien.

class LinqEntityBinding<T> : System.ComponentModel.BindingList<T> 
    where T : System.Data.Objects.DataClasses.EntityObject 
{ 
    public LinqEntityBinding(
     System.Data.Objects.ObjectContext context, 
     System.Data.Objects.DataClasses.EntityCollection<T> collection, 
     IList<T> list) 
     : base(list) 
    { 
     _context = context; 
     _collection = collection; 
    } 
    System.Data.Objects.ObjectContext _context; 
    System.Data.Objects.DataClasses.EntityCollection<T> _collection; 

    protected override object AddNewCore() 
    { 
     object obj = base.AddNewCore(); 
     _collection.Add((T)obj); 
     return obj; 
    } 

    public override void CancelNew(int itemIndex) 
    { 
     object obj = Items[itemIndex]; 
     _collection.Remove((T)obj); 
     if (((T)obj).EntityState != System.Data.EntityState.Detached) 
     { 
      _context.DeleteObject(obj); 
     } 
     base.CancelNew(itemIndex); 
    } 
} 

Alors, au lieu de:

bindingSource.DataSource = customer.Widgets; // unsorted 

Je:

bindingSource.DataSource = 
    new LinqEntityBinding<Widget>(db, customer.Widgets, 
    customer.Widgets.OrderBy(w => w.widgetness).ToList()); // sorted