Tuesday, December 15, 2009

LINQ : CopyToDataTable Where the Generic Type T Is Not a DataRow

Hi All,

Last week I was working on a LINQ2DataSet and LINQ2XML based application. There I happened to use .CopyToDataTable() method.

DataSet ds = new DataSet();

ds.ReadXml("C:\TestXML");

var query = from row in ds.Tables[0].AsEnumerable()

where row.Field<string>("IsActive") == "1"

select new { ID = row.Field<string>("ID"), UserName = row.Field<string>("UserName") };

DataTable dtResults = query.CopyToDataTable();

I got an error something like this:

The type 'AnonymousType#1' cannot be used as type parameter 'T' in the generic type or method 'System.Data.DataTableExtensions.CopyToDataTable<T>(System.Collections.Generic.IEnumerable<T>)'. There is no implicit reference conversion from 'AnonymousType#1' to 'System.Data.DataRow'.

This error will go if you select complete DataRow like this:

DataSet ds = new DataSet();

ds.ReadXml("C:\TestXML");

var query = from row in ds.Tables[0].AsEnumerable()

where row.Field<string>("IsActive") == "1"

select row;

DataTable dtResults = query.CopyToDataTable();

The root cause of this issue is the defination of CopyToDataTable ().

Simply right click on function name and select "GoTo Defination".

public static DataTable CopyToDataTable<T>(this IEnumerable<T> source) where T : DataRow;

You can see that CopyToDataTable<T> is restricted for DataRow by "where T : DataRow" clause.

In case you have to have this working on the purely generic type (i.e.runtime DataRow object) you need to use custom method CopyToDataTable2() for which you need to manually add these extra files to your project as mentioned on these links:

http://msdn.microsoft.com/en-us/library/bb669096.aspx

Namaste !

Anugrah Atreya

No comments: