-2

I am trying to convert DataTable into generic list List<T>, I am getting this error :

cannot convert lambda expression to type string because it is not a delegate type

I have gone through several threads posted here on SO regarding this, most of them suggested using Entity and Linq namespaces, but still I am getting same error.

Here is my code:

DataTable csvData = GetDataTableFromCSVFile(csv_file_path);

List<MyClass> lst = new List<MyClass>();
lst = (from l in csvData
      select new MyClass // getting red line under select
      {
       Address_1 = l.Address_1,
       //total of 29 columns
       Title = l.Title,
       Town_of_Birth = l.Town_of_Birth
      }).ToList();
Latika Agarwal
  • 973
  • 1
  • 6
  • 11
Abdul
  • 1,416
  • 9
  • 26
  • 57

3 Answers3

1

You can use AsEnumerable() extension method inside your linq query to get collection of DataRow's:

class MyClass
{
    public int MyProperty { get; set; }
}


public static void Main(string[] args)
{
    DataTable table = new DataTable();
    table.Columns.Add("MyProperty", typeof(int));
    table.Rows.Add(1);
    table.Rows.Add(2);
    table.Rows.Add(3);

    List<MyClass> result = (from t in table.AsEnumerable()
                            select new MyClass
                            {
                                MyProperty = t.Field<int>("MyProperty")
                            }).ToList();

}
SᴇM
  • 7,024
  • 3
  • 24
  • 41
1

for generic solution , you can try like as below by making use of generics

lst = (from dataRow in csvData.AsEnumerable()
          select Converter<MyClass>.Fill(dataRow)).ToList();

class Converter<T>
    {
        public static T Fill(DataRow Row)
        {

          Type typeParameterType = typeof(T);
         object retval = Activator.CreateInstance(typeParameterType);

            Dictionary<string, PropertyInfo> props = new Dictionary<string,PropertyInfo>();
            foreach (PropertyInfo p in retval.GetType().GetProperties())
                props.Add(p.Name, p);
            foreach (DataColumn col in Row.Table.Columns)
            {
                string name = col.ColumnName;
                if (Row[name] != DBNull.Value && props.ContainsKey(name))
                {
                    object item = Row[name];
                    PropertyInfo p = props[name];
                    if (p.PropertyType != col.DataType)
                        item = Convert.ChangeType(item, p.PropertyType);
                    p.SetValue(LogicObject, item, null);
                }
            }
        return (T)retval ;
        }
    }

you need to do like this , make use of AsEnumerable

lst = (from dataRow in csvData.AsEnumerable()
      select new MyClass // getting red line under select
      {
       Address_1 = Convert.ToString(dataRow["Address_1"]),
       //total of 29 columns
       Title = Convert.ToString(dataRow["Title"]),
       Town_of_Birth = Convert.ToString(dataRow["Town_of_Birth"])
      }).ToList();

when you are reading value of dataRow take care of null if some columns going to return null value.

Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
1

You can use Select() method also to enumerate in Lamda, as below:

var dt = new DataTable();
var x = from a in dt.Select() where a.HasErrors == false select new Test { MyProperty = a.ItemArray.Count() };