2012-09-15 160 views
1

我有這樣一個LINQ到dataTable中查詢:沒有CopyToDatatable()方法

`var ShowResult = from r in Result.AsEnumerable() 
          where Convert.ToInt32(r.Field<double>("ASLVAM")/r.Field<double>("GEST")) > 60 
          orderby Convert.ToInt32(r.Field<double>("ASLVAM")/r.Field<double>("GEST")) descending 
          select new 
          { 
           pascode = r.Field<string>("PAS_CODE"), 
           melli = r.Field<string>("CODEMELI"), 
           name = r.Field<string>("NAM"), 
           family = r.Field<string>("FAMILY"), 
           bycode = r.Field<string>("BAYGANI"), 
           jancode = r.Field<string>("CODEJANBAZ"), 
           darsad = r.Field<int>("DARSAD"), 
           ostan = r.Field<string>("OSTAN_N"), 
           vacode = r.Field<string>("VA_CODE"), 
           moin = r.Field<string>("VA_MOIN"), 
           onvan = r.Field<string>("TAFZILI"), 
           aslvam = r.Field<double>("ASLVAM"), 
           gest = r.Field<double>("GEST"), 
           //tededGestKol = Convert.ToInt32(r.Field<double>("ASLVAM")/r.Field<double>("GEST")), 
           mandeVam = r.Field<double>("MANDE_VAM"), 
           dPardakht = r.Field<string>("DATE_P") 
          };`<code> 

和我添加參考System.Data.DataSetExtentions使用CopyToDataTable()方法用於示出在數據網格我的查詢結果的看法,但這種方法沒,T添加到我的Inellisence, 我也用MSDN Sample使用這種方法,但這個時候,我得到這個錯誤: 「指定的轉換無效」 請幫助我,我能做些什麼來overcom這問題?

回答

4

CopyToDataTable()僅適用於您的查詢返回IEnumerable <'DataRow>。在你的查詢中,你正在返回一個匿名類型。匿名類型不包含CopyToDataTable()的擴展方法。你可以像這樣選擇整行,假設Result是一個DataTable。然後創建你的匿名類型。

 public static void Start() 
    { 
     DataTable Result = new DataTable(); 
     var ShowResult = from r in Result.AsEnumerable() 
         where Convert.ToInt32(r.Field<double>("ASLVAM")/r.Field<double>("GEST")) > 60 
         orderby Convert.ToInt32(r.Field<double>("ASLVAM")/r.Field<double>("GEST")) descending 
         select r; 

     DataTable newDataTbl = ShowResult.CopyToDataTable(); 
     var anonType = newDataTbl.AsEnumerable() 
      .Select(r => new 
         { 
          pascode = r.Field<string>("PAS_CODE"), 
          melli = r.Field<string>("CODEMELI"), 
          name = r.Field<string>("NAM"), 
          family = r.Field<string>("FAMILY"), 
          bycode = r.Field<string>("BAYGANI"), 
          jancode = r.Field<string>("CODEJANBAZ"), 
          darsad = r.Field<int>("DARSAD"), 
          ostan = r.Field<string>("OSTAN_N"), 
          vacode = r.Field<string>("VA_CODE"), 
          moin = r.Field<string>("VA_MOIN"), 
          onvan = r.Field<string>("TAFZILI"), 
          aslvam = r.Field<double>("ASLVAM"), 
          gest = r.Field<double>("GEST"), 
          //tededGestKol = Convert.ToInt32(r.Field<double>("ASLVAM")/r.Field<double>("GEST")), 
          mandeVam = r.Field<double>("MANDE_VAM"), 
          dPardakht = r.Field<string>("DATE_P") 
         } 
        ); 
    } 

代替前者的方法,你可以使用下面的擴展方法從列表<「T>創建一個數據表。

 using System; 
     using System.Collections.Generic; 
     using System.Linq; 
     using System.Text; 
     using System.Data; 
     using System.ComponentModel; 
     using System.Reflection; 

     namespace Common 
     { 
      public static class DataTableExtensions 
      { 
       public static DataTable ConvertToDataTable<T>(this IList<T> data) 
       { 
        PropertyDescriptorCollection properties = 
         TypeDescriptor.GetProperties(typeof(T)); 
        DataTable table = new DataTable(); 
        foreach (PropertyDescriptor prop in properties) 
         table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType); 
        foreach (T item in data) 
        { 
         DataRow row = table.NewRow(); 
         foreach (PropertyDescriptor prop in properties) 
          row[prop.Name] = prop.GetValue(item) ?? DBNull.Value; 
         table.Rows.Add(row); 
        } 
        table.AcceptChanges(); 
        return table; 
       } 

       public static DataRow ConvertToDataRow<T>(this T item, DataTable table) 
       { 
        PropertyDescriptorCollection properties = 
         TypeDescriptor.GetProperties(typeof(T)); 
        DataRow row = table.NewRow(); 
        foreach (PropertyDescriptor prop in properties) 
         row[prop.Name] = prop.GetValue(item) ?? DBNull.Value; 
        return row; 
       } 

       public static T ConvertToEntity<T>(this DataRow tableRow) where T : new() 
       { 
        // Create a new type of the entity I want 
        Type t = typeof(T); 
        T returnObject = new T(); 

        foreach (DataColumn col in tableRow.Table.Columns) 
        { 
         string colName = col.ColumnName; 

         // Look for the object's property with the columns name, ignore case 
         PropertyInfo pInfo = t.GetProperty(colName.ToLower(), 
          BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); 

         // did we find the property ? 
         if (pInfo != null) 
         { 
          object val = tableRow[colName]; 

          // is this a Nullable<> type 
          bool IsNullable = (Nullable.GetUnderlyingType(pInfo.PropertyType) != null); 
          if (IsNullable) 
          { 
           if (val is System.DBNull) 
           { 
            val = null; 
           } 
           else 
           { 
            // Convert the db type into the T we have in our Nullable<T> type 
            val = Convert.ChangeType(val, Nullable.GetUnderlyingType(pInfo.PropertyType)); 
           } 
          } 
          else 
          { 
           // Convert the db type into the type of the property in our entity 
           SetDefaultValue(ref val, pInfo.PropertyType); 
           if (pInfo.PropertyType.IsEnum && !pInfo.PropertyType.IsGenericType) 
           { 
            val = Enum.ToObject(pInfo.PropertyType, val); 
           } 
           else 
            val = Convert.ChangeType(val, pInfo.PropertyType); 
          } 
          // Set the value of the property with the value from the db 
          if (pInfo.CanWrite) 
           pInfo.SetValue(returnObject, val, null); 
         } 
        } 

        // return the entity object with values 
        return returnObject; 
       } 

       private static void SetDefaultValue(ref object val, Type propertyType) 
       { 
        if (val is DBNull) 
        { 
         val = GetDefault(propertyType); 
        } 
       } 

       public static object GetDefault(Type type) 
       { 
        if (type.IsValueType) 
        { 
         return Activator.CreateInstance(type); 
        } 
        return null; 
       } 

       public static List<T> ConvertToList<T>(this DataTable table) where T : new() 
       { 
        Type t = typeof(T); 

        // Create a list of the entities we want to return 
        List<T> returnObject = new List<T>(); 

        // Iterate through the DataTable's rows 
        foreach (DataRow dr in table.Rows) 
        { 
         // Convert each row into an entity object and add to the list 
         T newRow = dr.ConvertToEntity<T>(); 
         returnObject.Add(newRow); 
        } 

        // Return the finished list 
        return returnObject; 
       } 
      } 
     } 
+0

謝謝,在代碼結束我想綁定這個datatable到datagriview,它沒有任何問題嗎? –

+0

我用dataGridView1.DataSource = anonType;用於在DataGridView中顯示我的查詢數據,但沒有顯示,insted我使用dataGridView1.DataSource = anonType.ToList();但是這次我得到了這個錯誤信息:「指定的演員無效」 –

+0

@ozzy_mra要綁定到數據網格,您可以使用DataView。你創建你的表,然後使用DefaultView來創建一個基於列數組的新表。 newDataTbl.DefaultView.ToTable(false,new [] {「PAS_CODE」,「CODEMELI」,「etc ..」});有關更多信息,請參見此鏈接http://blogs.msdn.com/b/aconrad/archive/2005/09/16/469107.aspx –