Reputation: 8188
I am trying to use the function found here: DataTable to List<object>
public static IList<T> ConvertTo<T>(DataTable table)
{
if (table == null)
return null;
List<DataRow> rows = new List<DataRow>();
foreach (DataRow row in table.Rows)
rows.Add(row);
return ConvertTo<T>(rows);
}
the return statement is giving me an exception stating:
The best overloaded method match for 'Utilities.Utility.ConvertTo<T>(System.Data.DataTable)' has some invalid arguments
Can someone help me fix this error??
Upvotes: 0
Views: 1451
Reputation: 112259
First, you are returning a T
but not a IList<T>
. Secondly, how are you expecting a DataRow
to be converted to an unknown T
, especially if a row has several columns?
Try something like this
public static IList<IList<T>> ConvertTo<T>(DataTable table)
{
if (table == null)
return null;
List<IList<T>> rows = new List<IList<T>>();
foreach (DataRow row in table.Rows) {
rows.Add(row.ItemArray.Cast<T>().ToArray());
}
return rows;
}
UPDATE:
A custom object is something like this
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public decimal Salary { get; set; }
}
However, in that case a generic interface is not useful, since you would have to code for that specific class
public static IList<Employee> GetEmployees(DataTable table)
{
var employees = new List<Employee>();
if (table != null) {
foreach (DataRow row in table.Rows) {
var emp = new Employee();
emp.ID = (int)row["ID"];
emp.Name = (string)row["Name"];
emp.Salary = (decimal)row["Salary"];
employees.Add(emp);
}
}
return employees;
}
This code has to be different for different tables and cannot be generic. At least not without using Reflection and assuming that the properties have the same names as the table columns.
A solution not using some tricky Reflection
code or other magic tricks would be to define an interface like this
public interface IDataObject
{
void FillFromRow(DataRow row);
}
Then you declare Employee
or any other data classes like this
public class Employee : IDataObject
{
public int ID { get; set; }
public string Name { get; set; }
public decimal Salary { get; set; }
public void FillFromRow(DataRow row)
{
ID = (int)row["ID"];
Name = (string)row["Name"];
Salary = (decimal)row["Salary"];
}
}
Now you can use generics again
public static IList<T> GetItems<T>(DataTable table)
where T : IDataObject, new()
{
var items = new List<T>();
if (table != null) {
foreach (DataRow row in table.Rows) {
T item = new T();
item.FillFromRow(row);
items.Add(item);
}
}
return items;
}
Upvotes: 1
Reputation: 70513
Don't do it that way use Marc's amazing function ( https://stackoverflow.com/a/545429/215752 ) I mean really... that is exactly what you want.. right?
You need another function
public static IList<T> ConvertTo<T>(IList<DataRow> rows)
{
IList<T> list = null;
if (rows != null)
{
list = new List<T>();
foreach (DataRow row in rows)
{
T item = CreateItem<T>(row);
list.Add(item);
}
}
return list;
}
The question you link had a link in it. I'd suggest looking there for more info:
There you will find all the code, which I expect will compile. I won't vouch for the reliability or reasonably of using it however.
Upvotes: 1