I have a data table that includes a column holding IP addresses. I need to be able to filter the rows and remove all rows where IP address is in the range of, say, from 10.20.1.xxx to 10.20.15.xxx as well as 10.20.61.xxx. (i.e. exclude 10.20.1.xxx, 10.20.2.xxx, ..., 10.20.14.xxx, 10.20.15.xxx and 10.20.61.xxx).
I would do the following,
DataTable dt; //your datatable here
DataView dv = dt.DefaultView;
foreach (DataRow dr in dt.Rows)
{
if (Regex.IsMatch(dr["Column name of your IP"].ToString(), "regex to check IP") == false)
{
//Delete that row or something
}
else
{
//Do something else
}
}
DataTable tempTable = dv.ToTable();
//where temptable is your sorted and updated datatable
You can store this inside a method and call it to perform a check wherever you are binding or before that.
SQL
DELETE FROM sometable WHERE ip LIKE '10.20.1.%'
or
DELETE FROM sometable WHERE ip LIKE '10.20.%'
Linq
Without any code from you on how you're getting data from DB this will just get you a list of rows to be deleted, you can take it from there
var itemsToDelete = someList.Where(x => x.Ip.StartsWith("10.20.1"));
This worked for me:
Newtable = (from r in table.AsEnumerable()
where (
Convert.ToInt32(r.Field<string>("IP").Split('.')[2]) > 15 &&
Convert.ToInt32(r.Field<string>("IP").Split('.')[2]) != 61)
select r).CopyToDataTable();
Related
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.
}
I want to delete a particular row from a DataTable named dt.
For a table in SQL, I could do something like:
DELETE FROM dt
WHERE BASELINE_FOLDER = baselineSubfolder
AND BASELINE_FILE = baselineFilename
AND BASELINE_CHECKSUM = baselineChecksum;
Is there an equivalent LINQ statement for this?
Assuming you don't have the model's and only a DataTable (this is what I understand from the OP).
//Cast to enumerable of `DataRow` and filter on your condition
var rows = dt.Rows.Cast<DataRow>().Where(row => row["BASELINE_FOLDER"] == baselineSubFolder && row["BASELINE_FILE" == baselineFilename
&& row["BASELINE_CHECKSUM"] == baselineChecksum).ToArray();
//Loop through and remove the rows that meet the condition
foreach(DataRow dr in rows)
{
dt.Rows.Remove(dr);
}
you can convert the data table to list and can use RemoveAt() to do so.
You can convert it to list and use the below code
string baseLineFolder=dt.Rows["BASELINE_FOLDER"].ToString();
string baseLineFile=dt.Rows["BASELINE_FILE"].ToString();
string baseLineChecksum=dt.Rows["BASELINE_CHECKSUM"].ToString();
var dtresult = dt.AsEnumerable();
var result=(from r in dtresult
where(r.Field<string>("BASELINE_FOLDER")!=baseLineFolder)
&&(r.Field<string>("BASELINE_FILE")!=baseLineFile)
&&(r.Field<string>("BASELINE_CHECKSUM ")!=baseLineChecksum)
select r).ToList();
I'd like to filter items in my DataTable by whether a column value is contained inside a string array by converting it to an IEnumerable<DataRow>, afterwards I'd like to re-convert it to DataTable since that's what my method has to return.
Here's my code so far:
string[] ids = /*Gets string array of IDs here*/
DataTable dt = /*Databasecall returning a DataTable here*/
IEnumerable<DataRow> ie = dt.AsEnumerable();
ie = ie.Where<DataRow>(row => ids.Contains(row["id"].ToString()));
/*At this point I've filtered out the entries I don't want, now how do I convert this back to a DataTable? The following does NOT work.*/
ie.CopyToDataTable(dt, System.Data.LoadOption.PreserveChanges);
return dt;
I would create an empty clone of the data table:
DataTable newTable = dt.Clone();
Then import the rows from the old table that match the filter:
foreach(DataRow row in ie)
{
newTable.ImportRow(row);
}
Assuming that you want to filter the rows in-place, that is the filtered rows should be returned in the same DataTable that was created through the original database query, you should first clear the DataTable.Rows collection. Then you should copy the filtered rows to an array and add them sequentially:
ie = ie.Where<DataRow>(row => ids.Contains(row["id"].ToString())).ToArray();
dt.Rows.Clear();
foreach (var row in ie)
{
dt.Rows.Add(row);
}
An alternative way to achieve this could be to simply iterate through the rows in the DataTable once and delete the ones that should be filtered out:
foreach (var row in dt.Rows)
{
if (ids.Contains(row["id"].ToString()) == false)
{
row.Delete();
}
}
dt.AcceptChanges();
Note that if the DataTable is part of a DataSet that is being used to update the database, all modifications made to the DataTable.Rows collection will be reflected in the corresponding database table during an update.
I have DataTable with the following columns:
ClientID date numberOfTransactions price
ClientID is of type string and I need to ensure that its contents include "A-" and "N6" for every value in the table.
I need to delete all rows from the DataTable where this first column (ClientID) does not contain both "A-" and "N6" (some totals and other unnecessary data). How can I select and delete these rows specifically from the DataTable?
I know this:
foreach (DataRow row in table.Rows) // Loop over the rows.
{
//Here should come part "if first column contains mentioned values
}
I also know this
If (string.Contains("A-") == true && string.Contains("N6") == true)
{
//Do something
}
I need help how to implement this for first column of each row.
Try this:
EDIT: Totally messed up that last line, so if you tried it, try it now that I made it not stupid. =)
List<int> IndicesToRemove = new List<int>();
DataTable table = new DataTable(); //Obviously, your table will already exist at this point
foreach (DataRow row in table.Rows)
{
if (!(row["ClientID"].ToString().Contains("A-") && row["ClientID"].ToString().Contains("N6")))
IndicesToRemove.Add(table.Rows.IndexOf(row));
}
IndicesToRemove.Sort();
for (int i = IndicesToRemove.Count - 1; i >= 0; i--) table.Rows.RemoveAt(IndicesToRemove[i]);
try using this,
assuming dt as your Datatabe object and ClientID as your first column (hence using ItemArray[0])
for(int i=0; i<dt.Rows.Count; i++)
{
temp = dt.Rows[i].ItemArray[0].ToString();
if (System.Text.RegularExpressions.Regex.IsMatch(temp, "A-", System.Text.RegularExpressions.RegexOptions.IgnoreCase) || System.Text.RegularExpressions.Regex.IsMatch(temp, "N6", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
{
dt.Rows.RemoveAt(i);
i--;
}
}
Simple and straight forward solution... hope it helps
this should be more efficient, both in lines of Code and Time, try this :)
for(int x=0; x<table.Rows.Count;)
{
if (!table.Rows[x].ItemArray[0].contains("A-") && !table.Rows[x].ItemArray[0].contains("N6"))
table.Rows.RemoveAt(x);
else x++;
}
Happy Coding
Preface: C.Barlow's existing answer is awesome, this is just another route someone could take.
This is one way to do it where you never have to loop all the way through the original table (by taking advantage of the DataTable.Select() method):
DataTable table = new DataTable(); // This would be your existing DataTable
// Grab only the rows that meet your criteria using the .Select() method
DataRow[] newRows = table.Select("ClientID LIKE '%A-%' AND ClientID LIKE '%N6%'");
// Create a new table with the same schema as your existing one.
DataTable newTable = table.Clone();
foreach (DataRow r in newRows)
{
// Dump the selected rows into the table.
newTable.LoadDataRow(r.ItemArray, true);
}
And now you have a DataTable with only the rows you want. If necessary, at this point you could clear out the original table and replace it with the contents of the new one:
table.Clear();
table = newTable.Copy();
Edit: I thought of a memory optimization last night, you can just overwrite the existing table once you have the rows you need, which avoids the need for the temporary table.
DataTable table = new DataTable(); // This would be your existing DataTable
// Grab only the rows that meet your criteria using the .Select() method
DataRow[] newRows = table.Select("ClientID LIKE '%A-%' AND ClientID LIKE '%N6%'");
// Clear out the old table
table.Clear();
foreach (DataRow r in newRows)
{
// Dump the selected rows into the table.
table.LoadDataRow(r.ItemArray, true);
}
suppose i am having a database table with 20 records and of that i want to display only 10 records in the dataviewgrid control, how can i achieve this?
You can write a query like this:
SELECT * FROM (
SELECT TOP 10 * FROM (
SELECT TOP 20 * FROM MyTable ORDER BY MyID ASC
) AS NewTbl ORDER BY MyID DESC
) AS NewTbl2 ORDER BY MyID ASC
This selects records 11-20. If you want to select records 6-15 just change 20 to 15.
20 is the "last record to select" and 10 is the number of records before and up to 20.
Edit (After your comment about having all rows in a DataSet):
var newDS = new DataSet();
newDS.Tables.Add(oldDSWithAllRows.Tables["YourTableName"].Clone());
foreach (DataRow myDataRow in oldDSWithAllRows.Tables["YourTableName"].Rows)
{
if (/* Your criteria */)
{
newDS.Tables["YourTableName"].ImportRow(myDataRow);
}
}
myDataGridView.DataSource = newDS;
Select only the 10 records you want.
In SQL use the TOP clause:
SELECT TOP 10 * FROM myTable
use DataTable.Select
usage:
dataSet1.Tables[0].Select("Id>5");
or, better, DataView with a RowFilter, example here
you can set tha DataGridView.DataSource to this DataView
If you're using the latest version of C# you could filter your source with LINQ:
// change Skip to 10 to page through
var filtered = mydatasource.Skip(0).Take(10);
This assumes you've returned your SQL data as an IEnumerable<T>
Suppose we have the following table
DataTable dt = new DataTable();
int counter = 1;
dt.Columns.Add("ID");
dt.Columns.Add("Name");
for (int i = 1; i <= 20; i++)
{
DataRow dr = dt.NewRow();
dr["ID"] = i;
dr["Name"] = string.Format("Name{0}", i);
dt.Rows.Add(dr);
}
You can bind the grid this way:
this.GridView1.DataSource = dt.AsEnumerable().Take(10);
this.GridView1.DataBind();
but:
this can work if you did the following:
-Add two template fields to the gridview
-Add the following function to the code behind page:
protected object GetColumnValue(object Row,string columnName)
{
DataRow dr = Row as DataRow;
return dr[columnName];
}
Edit the DataBindings of the fields of the gridview to bind this way:
GetColumnValue(Container.DataItem,"ID") //for the first Field
GetColumnValue(Container.DataItem,"Name") //for the second field