2011-02-10 94 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