performing a select on a c# datatable - c#

I have a datatable with a bunch of rows in it, the first column is an Int32 and I want to perform a simple select like:
select * from MyDataTable where column1 = 234

Try this to get result as row array :
DataRow[] rows = myDataTable.Select("column1 = 234");
Or this to get dataview :
DataView myDataView = myDataTable.DefaultView;
myDataView.RowFilter = "column1 = 234";

var result = from row in table.AsEnumerable()
where row[0].Equals(42)
select row;
Or
var result = table.AsEnumerable().Where(row => row[0].Equals(42));

if you're talking of a System.Data.DataTable, you can use datatable.Rows.Find for searching a row by primaryKey, or datatable.Select for obtaining a array of rows that satisfy your condition.
// By DataTable's primary key
datatable.Rows.Find(234);
// By compound primary key
datatable.Rows.Find(234, 1, 4);
// by Select
datatable.Select("column1=234");
// by Compound Select
datatable.Select("column1=234 AND column2=1");

Related

use select statement to get Data from a DataTable

I have DataTable containing three columns, Name, Date and DialedNumber. I want to get rows on the basis of DialedNumber column having phone number like 03001234567 ...
I am filing datatable with an method return type is datatable.
{
DataTable dt = filldata();
}
Problem is how to use select statement to get rows having number 03001234567 or some other telephone number ?
Try this Suppose you have a variable **string str** which is having that telephone number which you want to get from that data table then you can use this
{
DataTable dt = filldata();
DataRow[] resut = dt.Select("DialedNumber ='" + str + "'");
}
It will return you those rows having same telephone number in column DialedNumber.
If you want to filter from the start, not getting all table rows every time, you should adjust your SQL statement:
SELECT * FROM Table WHERE DialedNumber = #dialedNumber
and in C# use SqlCommand.Parameters.AddWithValue(...) to add the #dialedNumber parameter to the query.
Try to use Linq to DataTable like this
var results = from myRow in dt.AsEnumerable()
where myRow.Field<String>("DialedNumber") == "03001234567"
select myRow;
You can use Linq to DataSet:
string number = "03001234567";
var rows = dt.AsEnumerable()
.Where(r => r.Field<string>("DialedNumber").Contains(number));
You even can project rows into strongly typed objects:
var people = from r in dt.AsEnumerable()
where r.Field<string>("DialedNumber").Contains(number)
select new {
Name = r.Field<string>("Name"),
Date = r.Field<DateTime>("Date"),
DialedNumber = r.Field<string>("DialedNumber")
};
Note: if you want to check exact match of dialed number, then instead of Contains(number) (which is equivalent of LIKE) use == number.
Try like this
private void GetRowsByFilter()
{
DataTable table = DataSet1.Tables["Table1"];
// Presuming the DataTable has a column named Date.
string expression;
expression = "DialedNumber ='03001234567 '";
DataRow[] foundRows;
// Use the Select method to find all rows matching the filter.
foundRows = table.Select(expression);
// Print column 0 of each returned row.
for(int i = 0; i < foundRows.Length; i ++)
{
Console.WriteLine(foundRows[i][0]);
}
}
DataTable.Select Method

Creating a datatable with only the rows that match a specific column name prefix using Linq in c#

For example my datatable is like this
A_1 A_2 A_3 ..... A_15 B_1.....B_10 C_1....C_10
x y z........ K
1 2 3.........4
I am trying to create seperate datatables for A,B and C which selects the rows based on column prefix, Also i just need row values in my new datatable.
var query = (from dc in table.Columns.Cast<DataColumn>()
where dc.ColumnName.Contains(prefix)
select table.Rows);
If the above is correct, how to proceed to insert the rows(which is in the query) to the new data table ?
You can create a DataView then copy to a DataTable selecting the columns that match your criteria:
string[] cols = (from dc in table.Columns.Cast<DataColumn>()
where dc.ColumnName.Contains(prefix)
select dc.ColumnName)
.ToArray();
DataView view = new DataView(table);
DataTable selected = view.ToTable(false, cols); // false ==> include "duplicate" rows

ToTable() doesn't return distinct records?

I am using datatable to return me distinct records but somehow its not returning me distinct records
I tried like
dt.DefaultView.ToTable(true, "Id");
foreach (DataRow row in dt.Rows)
{
System.Diagnostics.Debug.Write(row["Id"]);
}
It still returns me all the records. What could be wrong here?
UPDATE
My sql is as below
select t.Update ,t.id as Id, t.name ,t.toDate,t.Age from tableA t Where t.Id = 55
union
select t.Update ,t.id as Id, t.name ,t.toDate,t.Age from tableB t Where t.Id = 55
order by Id
Its very hard to do distinct in my query as there are many columns than mentioned here.
If you use a database it would be better to use sql to return only distinct records(e.g. by using DISTINCT, GROUP BY or a window function).
If you want to filter the table in memory you could also use Linq-To-DataSet:
dt = dt.AsEnumerable()
.GroupBy(r=>r.Field<int>("Id")) // assuming that the type is `int`
.Select(g=>g.First()) // take the first row of each group arbitrarily
.CopyToData‌​Table();
Note that the power of Linq starts when you want to filter these rows or if you don't want to take the first row of each id-group arbitrarily but for example the last row(acc. to a DateTime field). Maybe you also want to order the groups or just return the first ten. No problem, just use OrderBy and Take.
The issue is that you're not grabbing the new table:
var newDt = dt.DefaultView.ToTable(true, "Id");
foreach (DataRow dr in newDt.Rows) ...
the ToTable method doesn't modify the existing table - it creates a new one.
DataView view = new DataView(table);
DataTable distinctValues = view.ToTable(true, "Id");
you are not assigning the return value to any variable, try this
DataTable dtnew = dt.DefaultView.ToTable(true, "Id");
foreach (DataRow row in dtnew.Rows)
{
System.Diagnostics.Debug.Write(row["Id"]);
}

How to copy all the rows in a datatable to a datarow array?

I have two tables:
tbl_ClassFac:
ClassFacNo (Primary Key)
,FacultyID
,ClassID
tbl_EmpClassFac:
EmpID, (Primary Key)
DateImplement, (Primary Key)
ClassFacNo
I want to know all the Employees who are on a specific ClassFacNo. ie. All EmpID with a specific ClassFacNo... What I do is that I first search tbl_EmpClassFac with the EmpID supplied by the user. I store these datarows. Then use the ClassFacNo from these datarows to search through tbl_ClassFac.
The following is my code.
empRowsCF = ClassFacDS.Tables["EmpClassFac"].Select("EmpID='" + txt_SearchValueCF.Text + "'");
int maxempRowsCF = empRowsCF.Length;
if (maxempRowsCF > 0)
{
foundempDT = ClassFacDS.Tables["ClassFac"].Clone();
foreach (DataRow dRow in empRowsCF)
{
returnedRowsCF = ClassFacDS.Tables["ClassFac"].Select("ClassFacNo='" + dRow[2].ToString() + "'");
foundempDT.ImportRow(returnedRowsCF[0]);
}
}
dataGrid_CF.DataSource = null;
dataGrid_CF.DataSource = foundempDT.DefaultView;
***returnedRowsCF = foundempDT.Rows;*** // so NavigateRecordsCF can be used
NavigateRecordsCF("F"); // function to display data in textboxes (no importance here)
I know the code is not very good but that is all I can think of. If anyone has any suggestions please please tell me. If not tell me how do I copy all the Rows in a datatable to a datarow array ???
"How to copy all the rows in a datatable to a datarow array?"
If that helps, use the overload of Select without a parameter
DataRow[] rows = table.Select();
DataTable.Select()
Gets an array of all DataRow objects.
According to the rest of your question: it's actually not clear what's the question.
But i assume you want to filter the first table by a value of a field in the second(related) table. You can use this concise Linq-To-DataSet query:
var rows = from cfrow in tbl_ClassFac.AsEnumerable()
join ecfRow in tbl_EmpClassFac.AsEnumerable()
on cfrow.Field<int>("ClassFacNo") equals ecfRow.Field<int>("ClassFacNo")
where ecfRow.Field<int>("EmpId") == EmpId
select cfrow;
// if you want a new DataTable from the filtered tbl_ClassFac-DataRows:
var tblResult = rows.CopyToDataTable();
Note that you can get an exception at CopyToDataTable if the sequence of datarows is empty, so the filter didn't return any rows. You can avoid it in this way:
var tblResult = rows.Any() ? rows.CopyToDataTable() : tbl_ClassFac.Clone(); // empty table with same columns as source table

Group by column one, group by column two and then count column two on an EnumerableRowCollection

I have an EnumerableRowCollection in C# .Net, with two columns. I want to Group By the firstColumn, followed by the second column, then count the second column.
My EnumerableRowCollection is based on a DataTable that looks like this on a DataGridView:
If this were a MySQL table, I would achieve what I want like so:
SELECT `Product Name`,
`Upsell Price`,
Count(`Upsell Price`)
FROM `tblWhatever`
GROUP BY `Product Name`, `Upsell Price`;
I need this equivalent in LINQ
I have constructed the DataTable programmatically like so:
DataTable myDataTable = new DataTabl();
DataColumn myColumn = new DataColumn("My Column");
myDataTable.Columns.Add(myDataTable);
myDataTable.Rows.Add(new object[] { "whatever" });
myDataGridView.DataSource = myDataTable;
I found Daniel Schaffer's answer here, which helped me with the group by part, but I am stuck on the count as shown below:
var queryableData = myDataTable.AsEnumerable();
var result = from row in queryableData
group row by new { ProductName = row["Product Name"],
ProductPrice = row["Product Price"] };
How do I edit my LINQ query to allow me to group by column one, then group by column two and then count column two?
Try this :
var result = from row in queryableData
group row by new { ProductName = row["Product Name"],
ProductPrice = row["Product Price"] } into grp
select new { grp.Key.ProductName ,
grp.Key.ProductPrice,
Count = grp.Count() };

Categories