2013-07-02 4 views
1

J'ai une base de données SQL que j'ai importée en tant que modèle de données d'entité ADO.NET. Je remplis ensuite un DataGridView en utilisant Linq. J'ai étendu deux des tables avec des colonnes supplémentaires qui sont calculées à partir d'autres tables. Par exemple, j'ai une table Orders qui a des champs OrderNumber, DateApproved et RequestorID et ainsi de suite. J'ai aussi une table qui est le OrderDetails avec des champs comme SKU, OrderNUmber et QuanityOrdered. J'ai codé une nouvelle colonne IsBackOrdered pour la table des commandes qui calcule si un article (SKU) des OrderDetails est en attente.Linq ResultSet to DataTable

Lorsque je lie la table Commandes à DataGridView.DataSource tout fonctionne comme prévu. On m'a ensuite demandé de créer un filtre de recherche pour la table.

J'ai essayé de mapper BindingSource à la requête Linq, mais BindingSource attend un DataTable. J'ai trouvé une petite méthode soignée qui convertit Linq ResultSet à un DataTable (code ci-dessous) mais il barfs sur mes champs personnalisés (Columns) à cette ligne: dr [pi.Name] = pi.GetValue (rec, null) ?? DBNull.Value;

Merci d'avance pour votre avis ou pour toute idée utile que vous aimeriez offrir.

public static DataTable LinqToDataTable<T>(IEnumerable<T> varlist) 
     { 
      var dtReturn = new DataTable(); 

      // column names 
      PropertyInfo[] oProps = null; 

      if (varlist == null) 
       return dtReturn; 

      foreach (T rec in varlist) 
      { 
       // Use reflection to get property names, to create table, Only first time, others will follow 
       if (oProps == null) 
       { 
        oProps = rec.GetType().GetProperties(); 
        foreach (PropertyInfo pi in oProps) 
        { 
         Type colType = pi.PropertyType; 

         if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>))) 
         { 
          colType = colType.GetGenericArguments()[0]; 
         } 

         dtReturn.Columns.Add(new DataColumn(pi.Name, colType)); 
        } 
       } 

       DataRow dr = dtReturn.NewRow(); 

       foreach (PropertyInfo pi in oProps) 
       { 
        dr[pi.Name] = pi.GetValue(rec, null) ?? DBNull.Value; 
       } 

       dtReturn.Rows.Add(dr); 
      } 
      return dtReturn; 
     } 

Répondre

0

La propriété DataSource de BindingSource n'attend pas DataTable. C'est un objet de type, vous pouvez donc utiliser n'importe quelle liste comme source de données. Mais dans ce cas, pour pouvoir le filtrer, vous devez implémenter IBindingListView ou utiliser BindingList. Le deuxième cas est plus facile bien sûr. Jetez un oeil here pour plus d'informations.

+0

Nous vous remercions de votre compréhension. Pardonnez ma stupidité, mais votre lien semble montrer seulement la création d'une nouvelle classe de type BindingList. Je n'arrive pas à trouver comment convertir une liste en BindingList ou construire une requête linq BindingList. – Randy

+0

Au début, je suis désolé de vous dérouter avec la suggestion BindingList. Je l'ai vérifié et ça ne marche pas. La façon la plus simple que je vois maintenant est d'utiliser BindingListView générique que vous pouvez trouver [ici] (http://stackoverflow.com/a/5383203/1242916) – wunderbar