2011-02-10 53 views
7

我想運行一個linq查詢,但我需要結果作爲datatable,因爲我用它來存儲來自不同查詢的記錄在同一個viewstate對象中。使用DataContext從LINQ查詢填充DataTable最快的方法

以下兩個版本編譯,但返回一個空集。確切的錯誤是「值不能爲空 參數名稱:源」。 (是的,我已經檢查有數據):

MyDatabaseDataContext db = new MyDatabaseDataContext(conn); 
IEnumerable<DataRow> queryProjects = 
    (from DataRow p in db.STREAM_PROJECTs.AsEnumerable() 
    where p.Field<int>("STREAM_ID") == StreamID 
    select new 
    { 
     PROJECT_ID = p.Field<int>("PROJECT_ID"), 
     PROJECT_NAME = p.Field<string>("PROJECT_NAME") 
    }) as IEnumerable<DataRow>; 
DataTable results = queryProjects.CopyToDataTable<DataRow>(); 

...

//(from p in db.STREAM_PROJECTs.AsEnumerable() 
//where p.STREAM_ID == StreamID 
//select new 
//{ 
// p.PROJECT_NAME, 
// p.PROJECT_ID 
//}) as IEnumerable<DataRow>; 

在此thread的例子似乎並沒有在這種情況下,以工作,要麼。

我想我可以運行一個SQL查詢命令的老式的方式,但不是linq應該更快?

回答

19

你的問題是這樣的:

as IEnumerable<DataRow> 

as關鍵字進行安全投,而不是一個轉換,這好像你可能會認爲它做的。該as關鍵字是語義相同,這樣做:

IEnumerable<DataRow> queryProjects = 
    (IEnumerable<DataRow>)(from DataRow p in db.STREAM_PROJECTs.AsEnumerable() 
    where p.Field<int>("STREAM_ID") == StreamID 
    select new 
    { 
     PROJECT_ID = p.Field<int>("PROJECT_ID"), 
     PROJECT_NAME = p.Field<int>("PROJECT_NAME") 
    }); 

除非as版本時,它不能投你的查詢對象(這是一個IQueryable<T>,其中T是一個匿名類型)將不會拋出異常到IEnumerable<DataRow>(它不是)。

不幸的是,沒有內建的方法,我知道這將採取一個具體類型的枚舉(如在這個例子中的匿名類型),並將其變爲DataTable。編寫一個不會太複雜,因爲您基本上需要反射性地獲取屬性,然後遍歷集合並使用這些屬性在DataTable中創建列。我會在一些例子中發佈一個例子。

這樣的事情,放在一個靜態類,你是using一個命名空間中,應該提供一個擴展方法,將你想要做什麼:

public static DataTable ToDataTable<T>(this IEnumerable<T> source) 
{ 
    PropertyInfo[] properties = typeof(T).GetProperties(); 

    DataTable output = new DataTable(); 

    foreach(var prop in properties) 
    { 
     output.Columns.Add(prop.Name, prop.PropertyType); 
    } 

    foreach(var item in source) 
    { 
     DataRow row = output.NewRow(); 

     foreach(var prop in properties) 
     { 
      row[prop.Name] = prop.GetValue(item, null); 
     } 

     output.Rows.Add(row); 
    } 

    return output; 
} 
+0

我看 - 所以它只是隱藏InvalidCastException的?那麼我如何才能將它放入數據表? – JumpingJezza 2011-02-10 04:23:42