How to remove row from datatable within specific id in bottom line - c#

The code below choose the first row and remove the other row below with specific id. The things that i want is the last line within the id.
var dtremove = RemoveDuplicateRows(dt, "id);
This the extension
public DataTable RemoveDuplicateRows(DataTable dt, string colName)
{
Hashtable hTable = new Hashtable();
ArrayList duplicateList = new ArrayList();
//Add list of all the unique item value to hashtable, which stores combination of key, value pair.
//And add duplicate item value in arraylist.
foreach (DataRow drow in dt.Rows)
{
if (hTable.Contains(drow[colName]))
{
duplicateList.Add(drow);
}
else
hTable.Add(drow[colName], string.Empty);
}
//duplicateList.Sort();
//Removing a list of duplicate items from datatable.
foreach (DataRow dRow in duplicateList)
dt.Rows.Remove(dRow);
//Datatable which contains unique records will be return as output.
return dt;
}
The example of datatable.
id date
------------
A 1/1/2018
A 1/2/2018
A 1/3/2018
B 2/1/2018
B 2/2/2018
i want the result like this.
id date
------------
A 1/3/2018
B 2/2/2018

I tried not to change too much of your code, pretty sure it can be improved, but the changes below looks for the value and if it already exists in the dictionary, it replaces it: Thus, you will end up with the very last row instead of the first one. Also, it returns a new DataTable and the original one will stay intact.
public DataTable RemoveDuplicateRows(DataTable dt, string colName)
{
var uniqueRows = new Dictionary<string, DataRow>();
foreach (DataRow thisRrow in dt.Rows)
{
if (uniqueRows.ContainsKey(colName))
{
uniqueRows[colName] = thisRrow;
}
else
{
uniqueRows.Add(colName, thisRrow);
}
}
DataTable copy = dt.Copy();
copy.Rows.Clear();
foreach (var thisRow in uniqueRows)
{
copy.Rows.Add(thisRow.Value);
}
//Datatable which contains unique records will be return as output.
return copy;
}

Related

How to foreach through a list of datatables?

I have a list of 2 DataTables. I want to iterate through each of them, one at a time. How do I do this? There are 0 examples of going through a list of DataTables.
List<DataTable> test = new List<DataTable>();
foreach (DataRow dataRow in TEST.LIST)
{
string value = dataRow.Field<string>("Slave_IO_Running"); //Looks for "Slave_IO_Running" status.
if (value == "Yes")
{
results.Add(siteName + ": WORKING"); //adds working to the visual table
}
else
{
results.Add(siteName + ": REPLICATION ERROR"); //adds not working to the result list
}
break;
}
for each datatable you can use DataTable.Rows and for each row you can access the properties as row["columnName"] or traverse each column in the corresponding row
like
foreach(DataTable table in tables)
{
foreach(DataRow row in table.Rows)
{
foreach(DataColumn column in table.Columns)
{
Console.WriteLine(row[column]);
}
}
}
You can try it like this, assuming both tables contain the same columns:
foreach (DataRow dataRow in test.SelectMany(dt => dt.Rows.OfType<DataRow>()))
{
// your code using the rows
}

Remove (both) equal entries from DataTable

I want to remove equal entries from DataTable.
I tried DefaultView, but it only removes the equals and not all entries which including them.
DataView view = table1.DefaultView;
DataTable tbl = view.ToTable();
return tbl;
you can do this
public DataTable RemoveDuplicate(DataTable dataTable, string columname)
{
Hashtable hashTable = new Hashtable();
List<String> duplicates = new List<String>();
foreach (DataRow datarow in dataTable.Rows)
{
if (hashTable .Contains(datarow [columname]))
{
duplicateList.Add(datarow );
}
else
{
hashTable .Add(datarow [columname], string.Empty);
}
}
//Now remove the duplicates .
foreach (DataRow datarow in duplicates )
dataTable.Rows.Remove(datarow );
return dataTable;
}

Duplicate user are not allowing in gridview in ASP.NET C#

I have many checkbox lists for searching, but when I will search by any of the checkbox list search if any record will be two times in table means will not fill into gridview.
This line of code is not allowed duplicate values, if duplicate means allow single record.
if (newdt.TableName == dt.TableName) {
// see if filter is already present in the dataset
tableMatchFound = true;
// when the current filter is already present in the dataset
foreach (DataRow dr in dt.Rows)
ds.Tables[newdt.TableName].ImportRow(dr);
}
// importrow() adds distinct new subfilters to the existing filter, duplicate items are not added
if (!tableMatchFound)
ds.Tables.Add(dt);
Below is my full .cs code.
private DataTable list(String dbObject, String filterName, String filterValue,string PositonId,string Status) {
NameValuePairList objNameValuePairList = new NameValuePairList();
objNameValuePairList.Add(new NameValuePair("#FilterValue", filterValue, PositonId, Status));
objNameValuePairList.Add(new NameValuePair("#Action", "FilterBy" + filterName, PositonId, Status));
DataTable dt = dl.Search_RegisterationInfo(dbObject, objNameValuePairList, PositonId, Status);
return dt;
}
public DataTable list(String dbOject, FilterList myFilterList,string PositonId,string Status) {
// gets a collection(dataset) of all unique filters(datatables) and also group all subfilters(rows) under each filter
DataTable dt;
DataSet ds = new DataSet();
// a filter may be a Nationality or a Qualification
foreach (Filter item in myFilterList)
// a subfilter may be Indian or Expatriate under the filter Nationality
{
// another subfilter may be Bachelor degree or Master Degree under the filter Qualification
dt = list(dbOject, item.getFilterName, item.getFilterValue, PositonId,Status);
dt.TableName = item.getFilterName;
// datatables are named based on the filters
if (ds.Tables.Count == 0)
// so we get a collection of unique filters (datatables) in the dataset
ds.Tables.Add(dt);
// add new filter without checking, since for the first time, no conflicts are possible
else
{
bool tableMatchFound = false;
foreach (DataTable newdt in ds.Tables)
if (newdt.TableName == dt.TableName)
{
// see if filter is already present in the dataset
tableMatchFound = true;
// when the current filter is already present in the dataset
foreach (DataRow dr in dt.Rows)
ds.Tables[newdt.TableName].ImportRow(dr);
}
// importrow() adds distinct new subfilters to the existing filter, duplicate items are not added
if (!tableMatchFound)
ds.Tables.Add(dt);
}
// if the filter does not exist, add the new filter to the collection
}
// the entire collection of filters will contain duplicate items
// distinct items from the entire collection is filtered out in the next section
dt = ds.Tables[0].Clone();
// get the structure of the first filter as they all apply to the same table object
if (ds.Tables.Count == 1)
dt = ds.Tables[0];
// if there is only one filter, no filtering is required
else
// if there are more than one, compare each subfilter of every other filter with the subfilters of the first filter
foreach (DataRow dr in ds.Tables[0].Rows)
{
// each subfilter from the first filter is used as a pivot
int rowMatchFound = 1;
for (int i = 1; i < ds.Tables.Count; i++)
// search all filters except the first one
foreach (DataRow newdr in ds.Tables[i].Rows)
// select each subfilter from all the filter
if ((int)dr["RegistrationId"] == (int)newdr["RegistrationId"])
rowMatchFound++;
if (rowMatchFound == ds.Tables.Count)
// a match is found exactly once in all the filters
dt.ImportRow(dr);
// the final item is selected so that is is present in all the filters
}
return dt;
}
Please follow the link for more details of my question.
https://forums.asp.net/t/2078301.aspx?Duplicate+items+are+not+added+using+ASP+NET+C+

adding in SortedDictionary

I want to add table name as string and table value as arraylist if table name exist in same key add record as array list ...here showing key already exist . where i can modify :
SortedDictionary<string, ArrayList> DealInfo = new SortedDictionary<string, ArrayList>();
ArrayList Deal = new ArrayList();
string DealName=string.Empty;
foreach (DataTable table in RecentAddedDeal.Tables)
{
foreach (DataRow dr in table.Rows)
{
if (!DealInfo.ContainsKey(Convert.ToString(dr["DealTab"])))
{
DealName = Convert.ToString(dr["DealTab"]);
}
Deal.Add(dr);
DealInfo.Add(DealName, Deal);
}
}
It's hard to tell exactly what you want since your description says you want to use the TableName as the key, but your code is adding a column from the row as a key.
Going with the idea that the TableName should be the key, something like this should work:
var dealInfo = new SortedDictionary<string, List<DataRow>>();
foreach (DataTable table in RecentAddedDeal.Tables)
{
if (!dealInfo.ContainsKey(table.TableName))
{
dealInfo.Add(table.TableName, table.Rows.Cast<DataRow>().ToList());
}
}
Going with the idea that you want to key off a column in each row for the key, you could do something like:
var dealInfo = new SortedDictionary<string, List<DataRow>>();
foreach (DataTable table in RecentAddedDeal.Tables)
{
foreach (DataRow row in table.Rows)
{
var dealName = row["DealTab"].ToString();
if (dealInfo.ContainsKey(dealName))
{
dealInfo[dealName].Add(row);
}
else
{
dealInfo.Add(dealName, new List<DataRow> {row});
}
}
}
To fill a ListView with data from a row for a specific DealName, you can find the dictionary entry for that deal name and access the list of rows this way:
foreach (DataRow row in dealInfo["SomeDealName"])
{
// Here you have access to the rows where row["DealTab"] == "SomeDealName"
// You can fill a list view with some column value from the row like:
listView1.Add(row["SomeColumnName"].ToString());
}

How to build a DataTable from a DataGridView?

I may well be looking at this problem backwards but I am curious none the less. Is there a way to build a DataTable from what is currently displayed in the DataGridView?
To be clear, I know you can do this DataTable data = (DataTable)(dgvMyMembers.DataSource); however that includes hidden columns. I would like to build it from the displayed columns only.
Hope that makes sense.
So I ended up trying a combination of a couple of answers as that seemed best. Below is what I am trying. Basically I am creating the DataTable from the DataSource and then working backwards based on if a column is visible or not. However, after it removes a column I get a Collection was modified; enumeration operation may not execute on the next iteration of the foreach.
I am confused as I am not trying to modify the DataGridView, only the DataTable so what's up?
DataTable data = GetDataTableFromDGV(dgvMyMembers);
private DataTable GetDataTableFromDGV(DataGridView dgv)
{
var dt = ((DataTable)dgv.DataSource).Copy();
foreach (DataGridViewColumn column in dgv.Columns)
{
if (!column.Visible)
{
dt.Columns.Remove(column.Name);
}
}
return dt;
}
Well, you can do
DataTable data = (DataTable)(dgvMyMembers.DataSource);
and then use
data.Columns.Remove(...);
I think it's the fastest way. This will modify data source table, if you don't want it, then copy of table is reqired. Also be aware that DataGridView.DataSource is not necessarily of DataTable type.
I don't know anything provided by the Framework (beyond what you want to avoid) that would do what you want but (as I suspect you know) it would be pretty easy to create something simple yourself:
private DataTable GetDataTableFromDGV(DataGridView dgv) {
var dt = new DataTable();
foreach (DataGridViewColumn column in dgv.Columns) {
if (column.Visible) {
// You could potentially name the column based on the DGV column name (beware of dupes)
// or assign a type based on the data type of the data bound to this DGV column.
dt.Columns.Add();
}
}
object[] cellValues = new object[dgv.Columns.Count];
foreach (DataGridViewRow row in dgv.Rows) {
for (int i = 0; i < row.Cells.Count; i++) {
cellValues[i] = row.Cells[i].Value;
}
dt.Rows.Add(cellValues);
}
return dt;
}
one of best solution enjoyed it ;)
public DataTable GetContentAsDataTable(bool IgnoreHideColumns=false)
{
try
{
if (dgv.ColumnCount == 0) return null;
DataTable dtSource = new DataTable();
foreach (DataGridViewColumn col in dgv.Columns)
{
if (IgnoreHideColumns & !col.Visible) continue;
if (col.Name == string.Empty) continue;
dtSource.Columns.Add(col.Name, col.ValueType);
dtSource.Columns[col.Name].Caption = col.HeaderText;
}
if (dtSource.Columns.Count == 0) return null;
foreach (DataGridViewRow row in dgv.Rows)
{
DataRow drNewRow = dtSource.NewRow();
foreach (DataColumn col in dtSource .Columns)
{
drNewRow[col.ColumnName] = row.Cells[col.ColumnName].Value;
}
dtSource.Rows.Add(drNewRow);
}
return dtSource;
}
catch { return null; }
}
First convert you datagridview's data to List, then convert List to DataTable
public static DataTable ToDataTable<T>( this List<T> list) where T : class {
Type type = typeof(T);
var ps = type.GetProperties ( );
var cols = from p in ps
select new DataColumn ( p.Name , p.PropertyType );
DataTable dt = new DataTable();
dt.Columns.AddRange(cols.ToArray());
list.ForEach ( (l) => {
List<object> objs = new List<object>();
objs.AddRange ( ps.Select ( p => p.GetValue ( l , null ) ) );
dt.Rows.Add ( objs.ToArray ( ) );
} );
return dt;
}

Categories