2

class :

class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }
}

List

List<Foo> lst = new List<Foo>();

Datatable :

 DataTable dt = GetFromDb ()....

I want to fill lst with records from dt.

I've managed doing :

Array.ForEach(dt.AsEnumerable().ToArray(), y = > lst.Add(new Foo()
{
    Id = int.Parse(y["id"].ToString()), Name = y["name"].ToString()
}));

question :

  1. Can't I do something else like dt.AsEnumerable().Select(_ => fill lst ) ?

I know that part of the select signature (in this case ) is Func<datarow,void> which wont compile

But still , is there any other way of doing this besides the ugly way of mine ?

Lucas
  • 17,277
  • 5
  • 45
  • 40
Royi Namir
  • 144,742
  • 138
  • 468
  • 792

5 Answers5

7

Try this

var fooList = (from t in dt.AsEnumerable() 
         select new Foo { Id = t.Field<int>("Id"), 
                          Name= t.Field<string>("Name") }).ToList();

The AsEnumerable extension method on a DataTable will return a Collection of DataRows. then you do a projection from your Linq Result with required fields. Since it is dataRow type, you need to specify what each column type will be.

Shyju
  • 214,206
  • 104
  • 411
  • 497
7

Using LINQ to DataSet:

var foos = from row in dt.AsEnumerable()
           select new Foo()
           {
              Id = row.Field<int>("id"),
              Name = row.Field<string>("name")
           };

// create a new list
List<Foo> lst = foos.ToList();

// update: add items to an exisiting list
fooList.AddRange(foos);
Lucas
  • 17,277
  • 5
  • 45
  • 40
4

You are on the right track, you can do the following:

lst = dt.AsEnumerable().Select(y = > new Foo()
{
    Id = Convert.ToInt32(y["id"]), Name = y["name"] as string
}).ToList();

EDIT: To add to an existing list

I would normally just concatenate two lists:

lst = lst.Concat(dt.AsEnumerable().Select(...)).ToList();

However having seen ken2k's answer, I think I will now start using AddRange instead.

Shagglez
  • 1,522
  • 3
  • 21
  • 38
  • nice. What if I want to add items to an existing list ? ( not asked in question - I know) – Royi Namir Aug 06 '12 at 15:31
  • You must foreach over the list. Linq is a querying language for getting data, it is not well suited to processing inside the query. – Kaido Aug 06 '12 at 15:40
2

You could do:

List<Foo> lst = dt.AsEnumerable().Select(z => new Foo
{
    Id = int.Parse(z["id"].ToString()),
    Name = z["name"].ToString()
}).ToList();

EDIT:

If you want to append to an existing List<Foo> instance:

lst.AddRange(dt.AsEnumerable().Select(z => new Foo
{
    Id = int.Parse(z["id"].ToString()),
    Name = z["name"].ToString()
}));
ken2k
  • 48,145
  • 10
  • 116
  • 176
1

I got another solution via Rows property :

 List<Foo> results = (from DataRow myRow in dt.Rows
                               select new Foo()
                            {
                              Id =int.Parse( row["id"].ToString()),
                              Name = row["name"].ToString()
                             }).ToList();
Royi Namir
  • 144,742
  • 138
  • 468
  • 792