I have the following code, first I filter by a foreign key, but then with that result I need to filter more with dates.
But I cant understand the syntax of the select() method of a datarow array given below.
UC021_WizardStepSelectUnitDataSet.WizardStepSelectUnits_UnitsSelectedInOtherAgreementsRow[] datarows =
_uc021_WizardStepSelectUnitDataSet.WizardStepSelectUnits_UnitsSelectedInOtherAgreements.Select(
"UnitId = " + row.UnitID).Cast
<UC021_WizardStepSelectUnitDataSet.WizardStepSelectUnits_UnitsSelectedInOtherAgreementsRow>().ToArray();
DataRow[] dr = _uc021_WizardStepSelectUnitDataSet.
WizardStepSelectUnits_UnitsSelectedInOtherAgreements.Select(
"UnitId = " + row.UnitID);
if (datarows.Length > 0)
{
dr.Select("");
}
The Select on DataTable is similar to a Where clause you add to a query, in this case its filtering the records matching the row.UnitID which is to be found under column UnitId of the DataTable.
You can add multiple conditions by using AND within select like
.Select("UnitId = " + row.UnitID+ " AND IsActive='Y'")
Related
I am currently using the following LINQ statement to pull certain data out of my DataTable
var possibleRows = _Data.Select("Distance > " + (location.Distance - delta) + " AND Distance < " + (location.Distance + delta));
I would like to end up with a DataRow that contains an average of every column that was in the select statement above without having to iterate through each column. I have over 100 columns and all the data is numeric. Is there a simple way to do this?
You could just do something like:
var rows = possibleRows.Cast<DataRow>();
var averages = table.Columns.Cast<DataColumn>()
.Select(col => new {
Column = col,
Average = rows.Average(row => (double)row[col])
}).ToList();
Note this assumes double throughout.
Note this doesn't result in a DataRow; it results in a List<>, where each item in the list has the column and that column's average.
DataTable dtt = (DataTable)Session["ByBrand"];
var filldt = (dtt.Select("Price >= " + HiddenField1.Value + " and Price <= " + HiddenField2.Value + "")).CopyToDataTable();
this code is working fine when it found values in selected DataTable but it showing error when Values are not found in DataTable. So please tell me how to check if no record found.
Simply check if your Select returns anything?
DataTable dtt = (DataTable)Session["ByBrand"];
DataRow[] rows = dtt.Select("Price >= " + HiddenField1.Value + " and Price <= " + HiddenField2.Value + "");
if(rows.Length > 0)
{
var filldt = rows.CopyToDataTable();
}
Well, the Linq example from Tim is really nice, but to complete my answer.
The Select method returns Always a DataRow array also if there is no row selected, but then you cannot ask to build a datatable from this empty array. Think about it. What schema the CopyToDataTable should build for the resulting table if no rows are present in the array?
You have tagged Linq but you are using DataTable.Select which is an old method to filter a DataTable. Use Enumerable.Where and the strongyl typed Field extension method.
decimal priceFrom = decimal.Parse(HiddenField1.Value);
decimal priceTo = decimal.Parse(HiddenField2.Value);
var dtFiltered = dtt.AsEnumerable()
.Where(row => row.Field<decimal>("Price") >= priceFrom
&& row.Field<decimal>("Price") <= priceTo))
.CopyToDataTable();
Presuming that the type of the column is decimal, if it's a different type you need to use that in Field or convert it first.
Note that you need to add System.Linq(file) and a reference to System.Data.DataSetExtensions(project).
Update
but it showing error when Values are not found in DataTable
CopyToDataTable throws an exception if the input sequence is empty. In my opinion the best approach is to handle that case separately:
DataTable tblFiltered = dtt.Clone(); // clones only structure not data
var filteredRows = dtt.AsEnumerable()
.Where(row => row.Field<decimal>("Price") >= priceFrom
&& row.Field<decimal>("Price") <= priceTo));
if(filteredRows.Any())
{
tblFiltered = filteredRows.CopyToDataTable();
}
or this approach that might be more efficient since it doesn't need to use Any which can cause an additional full enumeration in worst case:
foreach(DataRow row in filteredRows)
{
tblFiltered.ImportRow(row);
}
I've been trying to find an answer online but I'm working with a DataTable and I want to filter all rows based on the column name in the table but I can't seem to get the filterExpression to work. Even though the syntax is wrong, this is basically what I want it to do....
DataRow[] row = sqlDT.Select(ColumnName = "Foo", "ASC", DataViewRowState.CurrentRows);
Thanks so much.
There are a few ways to accomplish this. I would suggest using LINQ to filter the rows:
sqlDT = sqlDT.AsEnumerable().Where(r => r.Field<string>("ColumnName") == "Foo").CopyToDataTable();
You can also use the Select method or the DefaultView.RowFilter property:
//select method
sqlDT = sqlDT.Select("ColumnName = 'Foo'").CopyToDataTable();
//row filter property
sqlDT.DefaultView.RowFilter = "ColumnName = 'Foo'";
sqlDT = sqlDT.DefaultView.ToTable();
EDIT
If you just want to filter out unneeded columns, use the DefaultView.ToTable() method:
sqlDT = sqlDT.DefaultView.ToTable(false, "Column1", "Column2", "Column3");
You are doing it in the wrong order,simply do it like this:
Datatable.rows(0//its count).item("column name");
You could loop it then with foreach and make a list
you should try something like this
DataRow[] row = sqlDT.Select("ColumnName =' " + Foo + " ' " , "ASC", DataViewRowState.CurrentRows);
I hope this work for you.
I am using a datatable created by program. In this datatable i want to insert values in some specified columns.
Initially I am inserting primary key values leaving remaining columns null, when I am querying datatable with recently inserted value in Primary column to update same row, I am facing error Missing operand after ID operator
Can any one tell me the exact issue.
I am trying following code:
dt.Rows.Add(1);
int insertedValue = 1;
DataRow[] dr = dt.Select("ID = '" + insertedValue.toString() + "'");
And the table structure after entring primary value is as follows.
ID Volumn1 Volumn2 volumn3
--------------------------------------
1
You can do this more cleanly with LINQ and make this a strongly typed operation.
Something like:
dt.Rows.Add(1);
int insertedValue = 1;
var result =
dt.AsEnumerable().Where( dr => dr.Field<int>( "ID" ) == insertedValue );
Working example:
DataTable dt = new DataTable();
dt.Columns.Add( "ID", typeof( int ) );
dt.Rows.Add( 1 );
var result = dt.AsEnumerable().Where( dr => dr.Field<int>( "ID" ) == 1 );
You can simply format the selection string as shown below:
DataRow[] dr = dt.Select(string.Format("ID ='{0}' ", insertedValue));
Feel free to let me know if this works for you.. Thanks
You do not need ' ' in your filter.
I think this should work:
DataRow[] dr = dt.Select("ID = " + insertedValue.toString());
By the way, reference System.Data.DataSetExtensions
If you are looking for a specific row and your datatable has a primary key you could use the Find method and target the primary key which would return just the row you want rather than an array:
DataRow foundRow = dt.Rows.Find([INSERT SEARCH PARAMETER HERE]);
if(foundRow != null)
{
TO SET A STRING EQUAL TO A FOUND VALUE:
string str = foundRow["COLUMN NAME / INDEX];
OR IF YOU ARE INSERTING A VALUE YOU CAN USE IT LIKE THIS:
foundRow["COLUMN NAME / INDEX"] = NEW VALUE;
}
select column of row
dt.Rows[0].Field<string>("MyColumnName")
DataTable distinctTable = dTable.DefaultView.ToTable(true,"ITEM_NO","ITEM_STOCK");
DataTable dtSummerized = new DataTable("SummerizedResult");
dtSummerized.Columns.Add("ITEM_NO",typeof(string));
dtSummerized.Columns.Add("ITEM_STOCK",typeof(double));
int count=0;
foreach(DataRow dRow in distinctTable.Rows)
{
count++;
//string itemNo = Convert.ToString(dRow[0]);
double TotalItem = Convert.ToDouble(dRow[1]);
string TotalStock = dTable.Compute("sum(" + TotalItem + ")", "ITEM_NO=" + dRow["ITEM_NO"].ToString()).ToString();
dtSummerized.Rows.Add(count,dRow["ITEM_NO"],TotalStock);
}
Error Message: Syntax error in aggregate argument: Expecting a single column argument with possible 'Child' qualifier.
Do anyone can help me out?
Thanks.
You might try this:
dTable.Compute("sum([" + TotalItem + "])","");
I.e enclose your column name in square brackets [ ]
The idea is from this post.
The problem is exactly about your DataType of the column. If you have a row with dynamically added columns without DataType like that (it may be a result of a manual calculation or cross-tab query-like)
myTable.Columns.Add("AddedColumn");
You will probably face with the column conversion issue.
Instead, If you change your add method with pointing DataType like below
myTable.Columns.Add("AddedColumn", typeof(System.Int32));
It will work I think. It's what I experienced & fixed before...
You want to write:
dTable.Compute("sum(CONVERT(ITEM_STOCK, 'System.Double'))",
"ITEM_NO='" + dRow["ITEM_NO"].ToString() + "'")
instead of:
dTable.Compute("sum(" + TotalItem + ")", "ITEM_NO="...
because it will translate to dTable.Compute("sum(value_of_TotalItem), "ITEM_NO="..., value_of_TotalItem is a double and is not a column name.
See DataTable.Compute
UPDATE:
try this:
DataTable distinctTable = dTable.Clone();
dTable.Columns.Add("ITEM_STOCK_D", typeof(Decimal),
"CONVERT(ITEM_STOCK, 'System.Decimal')");
foreach (DataRow dRow in dTable.Rows)
{
String itemNo = dRow["ITEM_NO"].ToString();
if(distinctTable.Select(String.Format("ITEM_NO = '{0}'",itemNo)).Length == 0)
{
double totalStock = Convert.ToDouble(dTable.Compute("SUM(ITEM_STOCK_D)",
String.Format("ITEM_NO = '{0}'", itemNo)));
distinctTable.Rows.Add(itemNo, totalStock.ToString());
}
}
dTable.Columns.Remove("ITEM_STOCK_D");
In my case the issue was with my query itself.
My query returned difference of two columns. Like, query="Select A,B,A-B from Table" and I was performing sum on datatable using compute function as dt.Compute("Sum(A-B)","").
So, datatable was unable to compute the sum of A-B column. I gave the difference column alias as query="Select A,B,(A-B) as AB from Table"
and dt.Compute("Sum(AB)","").
Thus, resolved the error.