I am trying to run a linq query but I need the result as a datatable as I am using that to store records from different queries in the same viewstate object.
The 2 versions below compile, but return an empty set. The exact error is “Value cannot be null.
Parameter name: source”. (and yes I have checked there is data):
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>;
The examples in this thread don’t seem to work in this situation either.
I guess I could just run a sql query command the old-fashioned way, but isn’t linq supposed to be quicker?
Your problem is this:
The
askeyword performs a safe cast, not a conversion, which it seems like you might think that it’s doing. Theaskeyword is semantically the same as doing this:Except the version with
aswon’t throw an exception when it fails to cast your query object (which is anIQueryable<T>, whereTis an anonymous type) to anIEnumerable<DataRow>(which it isn’t).Unfortunately, there is no built-in method that I’m aware of that will take an enumerable of a concrete type (like your anonymous type in this example) and turn it into a
DataTable. Writing one wouldn’t be too complicated, as you’d essentially need to get the properties reflectively then iterate over the collection and use those properties to create columns in aDataTable. I’ll post an example in a few.Something like this, placed in a static class within a namespace that you’re
using, should provide an extension method that will do what you want: