take top 10 or 20 rows from dynamic datatable - c#

I have 100 records in my Datable says to be in
DataTable dt=new DataTable();
dt have 100 of records say column name as sub_id(contain int datatype) and subheadername(contain nvarchar(150)) , I want top 20 records from this dt in ascending order
I am putting code as
//dtlcategories.DataSource = dt.AsEnumerable().OrderBy(x => x["subheadername"]).Take(20).ToList();
dtlcategories.DataSource = dt.Rows.Cast<DataRow>().OrderBy(x => x["subheadername"]).Take(20).ToList();
dtlcategories.DataBind();
Here dtlcategories is Datalist but on running error is coming as 'System.Data.DataRow' does not contain a property with the name 'subheadername'.
ANSWER IS SOLVED
dtlcategories.DataSource = dt.Rows.Cast<DataRow>().OrderBy(x => x["subheadername"]).Take(20).copytodatatable();
dtlcategories.DataBind();

There's a couple different ways you can do this using LINQ. These will both return the same results.
dt.AsEnumerable().OrderBy(x => x["subheadername"]).Take(20);
dt.Rows.Cast<DataRow>().OrderBy(x => x["subheadername"]).Take(20);
If you're going to use the result as the source of data for another control, you may need to call .ToList() after .Take(x).
Edit:
I changed the column name based on your edit. If you want to sort by id instead (you didn't specify), just replace "subheadername" with "sub_id".

This query fetches top 20 records from db and then orders them by the sub_id column.
var topTwenty = dt.AsEnumerable().Take(20).OrderBy(r => r.Field<int>("sub_id"));

dt.AsEnumerable().OrderBy(row => row["sub_id"]).Take(20);
This will return you IEnumerable. Now iterate through the IEnumerable and add them to another data table. Now your final data table is ready!!

this code orders data according to date and takes first 100 row.
var table = new DataTable();
var t = table.AsEnumerable();
var result = t.OrderByDescending(f => f.Field<DateTime>(new DataColumn("Date"))).Take(100);
Update:
var table = new DataTable();
var t = table.AsEnumerable();
var result = t.OrderBy(f => f.Field<String>(new DataColumn("subheadername"))).Take(20)

A possible solution:
DataRow[] rows = dt.Select("sub_id< 100 ");

Related

Filter DATATABLE Rows with multiple Values in columns

I have a DataTable (dt) with multiple columns which is the source to DataGridView. I am trying to filter this DataTable(dt) with a list of values of a particular column.
I need to filter the Below DataTable(dt) with the list of employee names.
EmpList = {'Pete','Alen'}
This is my DataTable
Employee
ID
Country
Pete
1
USA
Mark
2
UK
Alen
3
AUS
Output needed:
Employee
ID
Country
Pete
1
USA
Alen
3
AUS
I am trying it with the below code
if (EmpList.Any())
{
foreach(string item in EmpList)
{
var dataRows = from dataRow in dt.AsEnumerable()
where (dataRow.Field<string>("Employee").Contains(item))
select dataRow;
dt.Rows.Add(dataRows);
}
}
The problem is With this block of code, DataType(System.Data.EnumerableRowCollection[system.Data.DataRow]) is filling in the Rows of DataTable along with previous Data.
If you want to filter the DataTable, you can use the DefaultView.RowFilter, join the collection of values to be compared and use the IN() operator in the comparison:
var names = new[]{ "Allen", "Pete" };
var values = string.Join("', '", names);
dt.DefaultView.RowFilter = $"Employee IN('{values}')";
Note that the strings are joined using a comma and a single quote: ', '
To remove the filter, just set it to string.Empty.
If you want to return a new DataTable, you can use the CopyToDataTable method:
var dtFiltered = dt.AsEnumerable()
.Where(dr => names.Any(s => s.Equals(dr["Employees"]))).CopyToDataTable();
You can also assign the DataTable to itself:
dt = dt.AsEnumerable().Where(...).CopyToDataTable();
I assume you are already referencing System.Data.DataSetExtensions, since you're using AsEnymerable() in your code.

Change order of rows in DataTable in C#

Is it possible to change order of rows in DataTable so for example the one with current index of 5 moves to place with index of 3, etc.?
I have this legacy, messy code where dropdown menu get it's values from DataTable, which get it's values from database. It is impossible to make changes in database, since it has too many columns and entries. My original though was to add new column in db and order by it's values, but this is going to be hard.
So since this is only matter of presentation to user I was thinking to just switch order of rows in that DataTable. Does someone knows the best way to do this in C#?
This is my current code:
DataTable result = flokkurDao.GetMCCHABAKflokka("MSCODE");
foreach (DataRow row in result.Rows)
{
m_cboReasonCode.Properties.Items.Add(row["FLOKKUR"].ToString().Trim() + " - " + row["SKYRING"]);
}
For example I want to push row 2011 - Credit previously issued to the top of the DataTable.
SOLUTION:
For those who might have problems with ordering rows in DataTable and working with obsolete technology that doesn't supports Linq this might help:
DataRow firstSelectedRow = result.Rows[6];
DataRow firstNewRow = result.NewRow();
firstNewRow.ItemArray = firstSelectedRow.ItemArray; // copy data
result.Rows.Remove(firstSelectedRow);
result.Rows.InsertAt(firstNewRow, 0);
You have to clone row, remove it and insert it again with a new index. This code moves row with index 6 to first place in the DataTable.
If you really want randomness you could use Guid.NewGuid in LINQ's OrderBy:
DataTable result = flokkurDao.GetMCCHABAKflokka("MSCODE");
var randomOrder = result.AsEnumerable().OrderBy(r => Guid.NewGuid());
foreach (DataRow row in randomOrder)
{
// ...
}
If you actually don't want randomness but you want specific values at the top, you can use:
var orderFlokkur2011 = result.AsEnumerable()
.OrderBy(r => r.Field<int>("FLOKKUR") == 2011 ? 0 : 1);
You can use linq to order rows:
DataTable result = flokkurDao.GetMCCHABAKflokka("MSCODE");
foreach (DataRow row in result.Rows.OrderBy(x => x.ColumnName))
{
m_cboReasonCode.Properties.Items.Add(row["FLOKKUR"].ToString().Trim() + " - " + row["SKYRING"]);
}
To order by multiple columns:
result.Rows.OrderBy(x => x.ColumnName).ThenBy(x => x.OtherColumnName).ThenBy(x.YetAnotherOne)
To order by a specific value:
result.Rows.OrderBy(x => (x.ColumnName == 2001 or x.ColumnName == 2002) ? 0 : 1).ThenBy(x => x.ColumName)
You can use the above code to "pin" certain rows to the top, if you want more granular than that you can use a switch for example to sort specific values into sorted values of 1, 2, 3, 4 and use a higher number for the rest.
You can not change the order or delete a row in a foreach loop, you should create a new datatable and randomly add the rows to new datatable, you should also track the inserted rows not to duplicate
Use a DataView
DataTable result = flokkurDao.GetMCCHABAKflokka("MSCODE");
DateView view = new DateView(result);
view.Sort = "FLOKKUR";
view.Filter = "... you can even apply an in memory filter here ..."
foreach (DataRowView row in view.Rows)
{
....
Every data table comes with a view DefaultView which you can use, this way you can apply the default sorting / filtering in your datalayer.
public DataTable GetMCCHABAKflokka(string tableName, string sort, string filter)
{
var result = GetMCCHABAKflokka(tableName);
result.DefaultView.Sort = sort;
result.DefaultView.Filter = filter;
return result;
}
// use like this
foreach (DataRowView row in result.DefaultView)

How to Fetch Every Next 100 rows from DataTable C#

I am working on Windows Form Application i have a DataTable Which contains 1000 rows and for paging my DataGridView i am fetching first 100 records from DataTable like this
DataTable rec = dt.Rows.Cast<DataRow>().OrderBy(x => x["RegNo"]).Take(100).CopyToDataTable();
I have also tried this
DataTable recc = dt.Rows.Cast<DataRow>().OrderBy(x => x["RegNo"]).Take(100).Skip(100).CopyToDataTable();
Question:
how to fetch next 100 records from DataTable when user click on next page and so on
You can skip and take.
DataTable rec = dt.Rows.Cast<DataRow>().OrderBy(x => x["RegNo"]).Skip(100).Take(100).CopyToDataTable();
You can have a variable that tracks current page.
var currPage = 1;
var page_size = 100;
var skip = currPage * page_size; //if 100 is page size......
DataTable rec = dt.Rows.Cast<DataRow>().OrderBy(x => x["RegNo"]).Skip(skip).Take(page_size).CopyToDataTable();
You can use Skip() and Take() functions. Better option would be to send page index and rows count per page as parameter to your function:
DataTable rec = dt.Rows.Cast<DataRow>()
.OrderBy(x => x["RegNo"])
.Skip(rowsCount * pageIndex)
.Take(rowsCount)
.CopyToDataTable();

Filtering entire DataSet with many DataTables

I have a DataSet with many DataTables each containing many columns plus a column buildingID.
I would like to filter the entire DataSet by giving it a value for buildingID. I would like the rows in every table with a buildingID of, say 343.
Is there any quick possible way in C#?
You can use DataTable.Select, which returns filtered rows from a DataTable matching a criteria.
foreach (DataTable table in dataset.Tables) {
var rows = table.Select("buildingID = " + buildingId.ToString());
// Do stuff with filtered rows
}
To easily get all the rows that match your criteria, here's a LINQ expression:
var rows = dataset.Tables.SelectMany(
t => t.Select("buildingID = " + buildingId.ToString()));
What about this?
var ds1 = new DataSet();
foreach (DataTable dt in ds1.Tables)
{
var filtereddt = dt.AsEnumerable().Where(row => row.Field<int>("buildingID") == 1).ToList();
//you can add these lists to another list array or something like that.
}

c# all distincts value from datatable

I've found this piece of code that can be used to get all distinct values. But my datatable has 10 columns. The distinctValues only shows the columns I write in the toTable(); Is it possible to use this function, but also show the rest of the columns?
DataView view = new DataView(table);
DataTable distinctValues = view.ToTable(true, "Column1", "Column2");
Unless those columns you mention are the full key to the table, there is no guarantee that for a particular combination of those two columns the other columns will have exactly one value.
And if they were the key, then there would be no need to use a "distinct" filter.
You can use Linq-To-DataTable
var distinct = from row in table.AsEnumerable()
group row by new
{
Col1 = row.Field<string>("Column1"),
Col2 = row.Field<string>("Column2")
} into Group
select Group.First()
DataTable tblDistinct = distinctRows.CopyToDataTable();
(assuming that you just want an arbitrary row[the first])

Categories

Resources