30

How do you use LINQ (C#) to select the value in a particular column for a particular row in a datatable. The equivalent SQL would be:

select NAME from TABLE where ID = 0
starball
  • 20,030
  • 7
  • 43
  • 238
ianbeks
  • 2,198
  • 1
  • 23
  • 26

7 Answers7

32

Thanks for your answers. I didn't understand what type of object "MyTable" was (in your answers) and the following code gave me the error shown below.

DataTable dt = ds.Tables[0];
var name = from r in dt
           where r.ID == 0
           select r.Name;

Could not find an implementation of the query pattern for source type 'System.Data.DataTable'. 'Where' not found

So I continued my googling and found something that does work:

var rowColl = ds.Tables[0].AsEnumerable();
string name = (from r in rowColl
              where r.Field<int>("ID") == 0
              select r.Field<string>("NAME")).First<string>();

What do you think?

Himanshu
  • 31,810
  • 31
  • 111
  • 133
ianbeks
  • 2,198
  • 1
  • 23
  • 26
  • 1
    If you want to use '.AsEnumerable' be sure to add the dll 'System.Data.DataSetExtensions' and a using statement for it! – KennyZ May 11 '12 at 16:06
  • REVISED COMMENT FROM ABOVE : If you want to use '.AsEnumerable' be sure to add the dll 'System.Data.DataSetExtensions'! Do NOT ann a using statement for it! Just Using System.Data and having a reference for the .dll will get this to work. – KennyZ May 11 '12 at 16:30
  • 1
    Be aware that `AsEnumerable` will switch the context of your query so your `where/select` will be performed in memory and not on the DB side. – James Jan 27 '14 at 11:29
22
var name = from r in MyTable
            where r.ID == 0
            select r.Name;

If the row is unique then you could even just do:

var row = DataContext.MyTable.SingleOrDefault(r => r.ID == 0);
var name = row != null ? row.Name : String.Empty;
James
  • 80,725
  • 18
  • 167
  • 237
  • Worth noting that calling a SingleOrDefault call will actually select all the columns once translated literally into SQL (As it returns a MyTable object rather than an IQueryable). Depending on what else is in the table that may have a performance impact which the select method won't. On a typical table the readability is arguably worth the small performance difference but since the question was about equivalent SQL I thought it was worth clarifying. – fyjham Dec 10 '09 at 11:09
  • SingleOrDefault is most appropriately used when you are looking to retrieve a unique item from a set. Which by the sounds of it the OP is. – James Dec 10 '09 at 11:27
7

I notice others have given the non-lambda syntax so just to have this complete I'll put in the lambda syntax equivalent:

Non-lambda (as per James's post):

var name = from i in DataContext.MyTable
           where i.ID == 0
           select i.Name

Equivalent lambda syntax:

var name = DataContext.MyTable.Where(i => i.ID == 0)
                              .Select(i => new { Name = i.Name });

There's not really much practical difference, just personal opinion on which you prefer.

fyjham
  • 7,004
  • 2
  • 32
  • 40
  • I think your lambda answer is correct than the marked one. SingleOrDefault() would fetch all the columns of the row (this isn't what the OP requested, OP only requested for one column). The Where() and Select() combination would only fetch the required column than fetching all the columns. Plz correct me if I'm wrong. – gsk Apr 22 '13 at 07:40
  • 2
    Yeah, you're right. You can still of course do ".SingleOrDefault()" on the end (e.g: `string name = DataContext.MyTable.Where(i => i.ID == 0).Select(i => i.Name).SingleOrDefault();` would only query the 1 column back). There's nothing inherently "fetch-all" about SingleOrDefault, you just need to chain the queries for that. Having said that, the performance overhead is typically negligible unless you have some very large data in the other columns. – fyjham Apr 29 '13 at 01:58
4

If the return value is string and you need to search by Id you can use:

string name = datatable.AsEnumerable().Where(row => Convert.ToInt32(row["Id"]) == Id).Select(row => row.Field<string>("name")).ToString();

or using generic variable:

var name = datatable.AsEnumerable().Where(row => Convert.ToInt32(row["Id"]) == Id).Select(row => row.Field<string>("name"));
Tunaki
  • 132,869
  • 46
  • 340
  • 423
mbadeveloper
  • 1,272
  • 9
  • 16
  • 3
    You can also use: string name = datatable.AsEnumerable().Where(row => Convert.ToInt32(row["Id"]) == Id).Select(row => row.Field("name")).First(); – mbadeveloper Sep 11 '16 at 14:11
  • to mbaddeveloper: That comment about first is pretty important if you are just trying to get one field from one row. That worked great! – j.hull Aug 28 '19 at 15:51
1
var name = from DataRow dr in tblClassCode.Rows where (long)dr["ID"] == Convert.ToInt32(i) select (int)dr["Name"]).FirstOrDefault().ToString() 
Tomasz Jakub Rup
  • 10,502
  • 7
  • 48
  • 49
0
var x  =  from row in table
          where row.ID == 0
          select row

Supposing you have a DataTable that knows about the rows, other wise you'll need to use the row index:

where row[rowNumber] == 0

In this instance you'd also want to use the select to place the row data into an anonymous class or a preprepared class (if you want to pass it to another method)

Chris
  • 2,447
  • 1
  • 21
  • 27
0

Use linq and set the data table as Enumerable and select the fields from the data table field that matches what you are looking for.

Example

I want to get the currency Id and currency Name from the currency table where currency is local currency, and assign the currency id and name to a text boxes on the form:

DataTable dt = curData.loadCurrency();
            var curId = from c in dt.AsEnumerable()
                        where c.Field<bool>("LocalCurrency") == true
                        select c.Field<int>("CURID");

            foreach (int cid in curId)
            {
                txtCURID.Text = cid.ToString();
            }
            var curName = from c in dt.AsEnumerable()
                          where c.Field<bool>("LocalCurrency") == true
                          select c.Field<string>("CurName");
            foreach (string cName in curName)
            {
                txtCurrency.Text = cName.ToString();
            }
Ashraf Sada
  • 4,527
  • 2
  • 44
  • 48