tags:

views:

31

answers:

2

assuming we use this on a table using "select * from table " ?

i want to create an array of classes

that use filed names (of the datatable) as class field names initalise them with the datatable fields

is it possible ? if so please help :) soory for the spelling my writen english is not that good but i hope i was clear

+1  A: 

This is a great time to use anonymous types

var query = (from row in DataTable.Rows.Cast<DataRow>()
            select new 
            {
                 ID = row.Field<int>("ID"),
                 Name = row.Field<string>("Caption"),
                 \\etc etc etc
            }).ToArray();

If you already have a class to store the results you could just as easily replace the anonymous type with that class (or use a Tuple in 4.0)

If you do this frequently you could write an extension method that uses reflection to match up data columns with the names of properties in the class array you are trying to generate

erash
A: 

that use filed names (of the datatable) as class field names initalise them with the datatable fields

The only way to do that would be to generate a class at runtime, which is (a) not easy and (b) usually not very useful because the code that will use this class won't know the names of the class members.

You could use the dynamic features of C# 4 to build a list of ExpandoObjects:

Func<DataRow, dynamic> projection =
    r =>
    {
        IDictionary<string, object> exp = new ExpandoObject();
        foreach (DataColumn col in r.Table.Columns)
            exp[col.ColumnName] = r[col];
        return exp;
    };

dynamic[] objects = dataTable.AsEnumerable().Select(projection).ToArray();

...

dynamic o = objects[0];

int id = o.Id;
string name = o.Name;

But then you loose the benefits of strong typing...

I think a more interesting idea would be to project the data rows to existing classes, based on the member names and data column names:

public T DataRowToObject<T>(DataRow row) where T : new()
{
    var properties = typeof(T).GetProperties().Where(p => p.CanWrite);
    var columns = row.Table.Columns.Cast<DataColumn>();

    // Match properties of T with DataTable columns
    var common =
        from p in properties
        from c in columns
        where c.ColumnName == p.Name
        && p.PropertyType.IsAssignableFrom(c.DataType)
        select p;

    T obj = new T();
    foreach (var prop in common)
    {
        if (!row.IsNull(prop.Name))
        {
            object value = row[prop.Name];
            prop.SetValue(obj, value, null);
        }
    }
    return obj;
}

...

MyClass[] objects = dataTable.AsEnumerable().Select(row => DataRowToObject(row)).ToArray();
Thomas Levesque