How to declare datarow outside foreach loop? - c#

I am using foreach loop and inside that loop I declared datarow
DataSet ds = Business.Site.GetSiteActiveModulesWithStatus(siteId);
foreach (DataRow dr in ds.Tables[0].Rows)
How can I implement this datarow outside foreach loop and how can I use for loop instead of foreach loop?

To loop in a for:
for(int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
//To acess the row
DataRow row = ds.Tables[0].Rows[i];
}
Outside the for, to acess a specific DataRow you can do like this:
//Change 0 to other numbers to acess other rows
DataRow row = ds.Tables[0].Rows[0];

To access the row variable outside of the loop, you simple have to declare it outside:
DataRow rowFound = null;
for(int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
var currentRow = ds.Tables[0].Rows[i];
if(true /*To do: define some matching criteria*/)
{
rowFound = currentRow;
}
}
if(rowFound != null)
{
// We found some matching, what shall we do?
}
But you could write the same also in a LINQish style:
var rowFound = ds.Tables[0].AsEnumerable()
.Where(row => true /*To do: define some matching criteria*/)
.FirstOrDefault();
All code in this answer is untested.

Related

Looping over DataRow to compare current row data and previous row data

I need to iterate over a DataRow in gridview, to compare the values from the current row and previous row. Appreciate if someone could help on this issue. I'm new
I am currently iterating like this, but i dont know how to continue:
//Check if current row ACTIVITY = LOAD_A and previous row ACTIVITY = LOAD_B is true , then store the
value and do the sum calculation.
foreach (DataRow sda in dt.Rows)
{
if (sda.Field<string>("ACTIVITY") == "LOAD_A")
{
}
}
As devNull already mentioned you can use a variable to hold the value of the previous iteration of the foreach loop.
This could look like this:
DataRow previousDr = null;
foreach (DataRow sda in dt.Rows)
{
if (previousDr != null)
{
if (sda.Field<string>("ACTIVITY") == "LOAD_A" &&
previousDr.Field<string>("ACTIVITY") == "LOAD_B")
{
//Store value und do calculation.
}
}
previousDr = sda;
}
You can use for statement and indexer property of DataRow to accomplish this
DataColumn column = table.Columns["ACTIVITY"];
for (int index = 1; index < table.Rows.Count; ++index)
{
if (table.Rows[index - 1].Field<string>(column) == "LOAD_B" && // previous row
table.Rows[index].Field<string>(column) == "LOAD_A") // current row
{
// do somthing
}
}

Unable to move row from one datatable to another

I have asked a question previously based on the errors of this code. However, after the suggestions given, there is no more error. However, the data from the row in queue table would not move to the the missedQueue table.
I'm not sure why it won't work :(
this is my code:
DataSet queue = DBMgr.GetDataSet("SELECT * FROM queue");
DataTable missedQueue = queue.Tables[0].Clone();
DataRow dr = queue.Tables[0].NewRow();
for (int i = 0; i < queue.Tables[0].Columns.Count; i++)
{
dr[queue.Tables[0].Columns[i].ColumnName] = queue.Tables[0].Rows[0][i];
}
missedQueue.Rows.Add(dr.ItemArray);
}
Your DataRow should be of missedQueue table and add the row inside loop like
DataRow dr = null;
for (int i = 0; i < queue.Tables[0].Columns.Count; i++)
{
dr = missedQueue.NewRow();
dr[queue.Tables[0].Columns[i].ColumnName] = queue.Tables[0].Rows[0][i];
missedQueue.Rows.Add(dr);
}

how to clone/copy a datatable with only first n columns using linq

I have a datatable containing over 100 columns, how ever I need to strip out all columns
except first 11 columns.
I need to retain data of 1st 11 columns.
I am doing it with following code
public DataTable validdatatable(DataTable table)
{
DataTable dt = new DataTable();
for (int i = 0; i < 11; i++)
{
DataColumn dc = new DataColumn();
dc.ColumnName = table.Columns[i].ColumnName;
dc.DataType = table.Columns[i].DataType;
dt.Columns.Add(dc);
}
for (int i = 0; i < table.Rows.Count; i++)
{
object[] ob = table.Rows[i].ItemArray;
...
...
}
return dt;
}
This methods works but is too heavy on CPU and Ram.
Is there any other method with which I can proceed?
Try this:
public DataTable validdatatable(DataTable table)
{
var dt = table.Columns.Cast<DataColumn>().Take(11);
return dt.CopyToDataTable();
}
Or Something like this. It will give you at least a way to work on it.
Note that You need to add a reference to the assembly: System.Data.DataSetExtensions.dll then you can write your function like above.
You can try this. The only difference would be instead of object[] ob = table.Rows[i].ItemArray it will just grab the first 11 columns using the index and make an array out of that (itemArray will make an array of all 100 columns). Still doubt this will solve your memory issues if you are that tight but it's probably worth a shot.
var copyDt = new DataTable();
for (var i = 0; i < 11; i++)
{
copyDt.Columns.Add(dataTable.Columns[i].ColumnName, dataTable.Columns[1].DataType);
}
copyDt.BeginLoadData();
foreach (DataRow dr in dataTable.Rows)
{
copyDt.Rows.Add(Enumerable.Range(0, 11).Select(i => dr[i]).ToArray());
}
copyDt.EndLoadData();

C# Datatable query

I want to search two string in datarows.For example;
string1="ex"
string2="ex2"
row1={'ex','ex2','ex3'....}---->True
row2={'ex3','ex1','ex2'....}---->True
row3={'ex2','ex5','ex6'....}---->False
Each line must have a value of two strings..
For This,
for (counter = 0; counter < array.Count; counter++)
{
int index=0;
ArrayList array3 = new ArrayList();
array3 = Split(array[counter].ToString());
foreach (DataRow row2 in data.Rows)
foreach (object obje in row2.ItemArray)
{
//Proceeds
}
}
}
I coding something.But I do not want to deal with pollution in the code...
Is there an easy way to select method?
var result = data.AsEnumerable()
.Where(r => r.ItemArray.Contains(string1) || r.ItemArray.Contains(string2))
Try to do something like this:
first define a DataView
DataView dv = new DataView(dt) where dt is a DataTable.
After apply RowFilter
dv.RowFilter = "CONTAINS(ColName, 'ex1') AND CONTAINS(ColName, 'ex2')".
Hope this helps.

How can I know a row index while iterating with foreach?

in the next example how can I know the current row index?
foreach (DataRow temprow in temptable.Rows)
{
//this.text = temprow.INDEX????
}
You have to create one yourself
var i = 0;
foreach (DataRow temprow in temptable.Rows)
{
this.text = i;
// etc
i++;
}
or you can just do a for loop instead.
I have a type in MiscUtil which can help with this - SmartEnumerable. It's a dumb name, but it works :) See the usage page for details, and if you're using C# 3 you can make it even simpler:
foreach (var item in temptable.Rows.AsSmartEnumerable())
{
int index = item.Index;
DataRow value = item.Value;
bool isFirst = item.IsFirst;
bool isLast = item.IsLast;
}
If you can use Linq, you can do it this way:
foreach (var pair in temptable.Rows.Cast<DataRow>()
.Select((r, i) => new {Row = r, Index = i}))
{
int index = pair.Index;
DataRow row = pair.Row;
}
You actually Don't. One of the beauties with foreach is that you don't have the extra set of code handling incrementing and checks on the length.
If you want to have your own Index you would have to do something like this
int rowindex = 0;
foreach (DataRow temprow in temptable.Rows)
{
//this.text = temprow.INDEX????
this.text = rowindex++;
}
int rowIndex = temptable.Rows.IndexOf(temprow);
It's not possible with a standard foreach loop. The simplest way is to use a for loop
for ( int i = 0; i < temptable.Rows.Count; i++ ) {
DataRow temprow = (DataRow)temptable.Rows[i];
...
}
Another option is to use an extension method
public static void ForEachIndex<T>(this IEnumerable<T> e, Action<T,int> del) {
var i = 0;
foreach ( var cur in e ) {
del(cur,i);
}
}
...
temptable.Rows.Cast<DataRow>.ForEachIndex((cur,index)
{
...
});
Hey there's a much faster way I think. No iteration required!
First, declare a static variable for the Friend RowID Field of the DataRow:
Private Shared RowIDFieldInfo As System.Reflection.FieldInfo = GetType(DataRow).GetField("_rowID", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Instance)
Then All you need to do to use it is:
RowIDFieldInfo.GetValue(MyDataRow) - 1
I have not tested this after resorting or filtering.
In my case I haven't a need to do that, so this works.
Better late than never...
foreach (DataRow temprow in temptable.Rows)
{
temptable.Rows.IndexOf(temprow);
}
Write any Cell number and get RowIndex
foreach (var item in datagridview.Rows)
{
//TextBox1.Text= item.Cells[0].RowIndex.ToString();
}
Either use a for-loop, or use an integer follow along:
int count =0;
foreach (DataRow temprow in temptable.Rows)
{
//count is the index of the row in the array temptable.Rows
//this.text = temprow.INDEX????
++count;
}
You can use the standard for loop to get the index
for(int i=0; i<temptable.Rows.Count; i++)
{
var index = i;
var row = temptable.Rows[i];
}
While LFSR's answer is right, I'm pretty sure calling .IndexOf on just about any collection/list is going to enumerate the list until it finds a the matching row. For large DataTable's this could be slow.
It might be better to for (i = 0; i < temptable.Rows.Count; i++) { ... } over the table. That way you have the index without imposing a find-the-index tax.
The alternative way to retrieve data by using index instead of using column name
foreach (DataRow temprow in temptable.Rows)
{
String col1 = temprow[0].ToString().Trim();
String col2 = temprow[1].ToString().Trim();
}
Hope it help

Categories

Resources