我正在尝试运行linq查询,但我需要将结果作为数据表,因为我使用它来存储来自同一viewstate对象中不同查询的记录。
下面的两个版本编译,但返回一个空集。确切的错误是“值不能为空。 参数名称:source“。(是的,我已检查过数据):
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应该更快吗?
答案 0 :(得分: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
是匿名类型)转换为{时,不会引发异常{1}}(事实并非如此)。
不幸的是,我没有内置的方法可以采用可枚举的具体类型(比如本例中的匿名类型)并将其转换为IEnumerable<DataRow>
。编写一个不会太复杂,因为您基本上需要反射性地获取属性,然后遍历集合并使用这些属性在DataTable
中创建列。我将在一些例子中发布一个例子。
这样的东西放在你DataTable
的命名空间中的静态类中,应该提供一个可以做你想做的扩展方法:
using