2

I have this code

foreach (DataRow row in dt.Rows)
{
  Debug.WriteLine("Start of Row");
  for (int i = 0; i < row.ItemArray.Length; i++) 
  {
    string val = row.ItemArray[i].ToString();
    row.ItemArray[i] = "My New Value";

    Debug.WriteLine("val: {0}, new: {1}", val, row.ItemArray[i].ToString());
  }
}

yet the value never gets updated. I am not sure why.

Start of Row
val: 2/02/2012, new: 2/02/2012
val: ac, new: ac
val: ac, new: ac
val: 515.00, new: 515.00

Edit

Some more tries

  for (int i = 0; i < dt.Rows.Count; i++)
            {
                DataRow row = dt.Rows[i]; 
                for (int x = 0; x < row.ItemArray.Length; x++)
                {
                    string val = row.ItemArray[x].ToString();
                    row.ItemArray.SetValue("My New Value", x);

                    Debug.WriteLine("val: {0}, new: {1}", val, row.ItemArray[x].ToString());
                }
            }

val: 2/02/2012, new: 2/02/2012
val: ac, new: ac
val: ac, new: ac
val: 515.00, new: 515.00

Another try

 for (int i = 0; i < dt.Rows.Count; i++)
            {
                DataRow row = dt.Rows[i]; 
                for (int x = 0; x < row.ItemArray.Length; x++)
                {
                    string val = row.ItemArray[x].ToString();
                    row[i] = "My New Value";

                    Debug.WriteLine("val: {0}, new: {1}", val, row.ItemArray[x].ToString());
                }
            }

gives me

System.Data.ReadOnlyException was unhandled by user code
  Message=Column 'Date' is read only.
  Source=System.Data
  StackTrace:
       at System.Data.DataRow.set_Item(DataColumn column, Object value)
       at System.Data.DataRow.set_Item(Int32 columnIndex, Object value)
       at CCRecomendator.Framework.Services.CreditCardRecommendatorService.ParseTransactions(Stream stream) in
       at CCRecomendator.WebUI.Controllers.RecommendController.UploadTransactions(HttpPostedFileBase file) in
       at lambda_method(Closure , ControllerBase , Object[] )
       at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
       at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
  InnerException: 

So maybe the stuff is readonly or something?

I am using filehelpers it is creating the datatable and it's rows. Not sure if it is doing something funky that is stopping me from doing what I want to do.

chobo2
  • 83,322
  • 195
  • 530
  • 832

5 Answers5

8

Instead of ItemArray, just access the index:

foreach (DataRow row in dt.Rows)
{
  Debug.WriteLine("Start of Row");
  for (int i = 0; i < row.ItemArray.Length; i++) 
  {
    string val = row[i].ToString();
    row[i] = "My New Value";

    Debug.WriteLine("val: {0}, new: {1}", val, row[i].ToString());
  }
}
LarsTech
  • 80,625
  • 14
  • 153
  • 225
  • Thanks for posting this. I've never seen ItemArray. Was going to post, well, this. :) – Nick Vaccaro Feb 09 '12 at 22:30
  • @chobo2 This worked on my test. Given your error, your "column" is set for `ReadOnly=True`. So you need to turn that off, or obviously not try changing a readonly column. – LarsTech Feb 09 '12 at 22:36
  • Ya that's what I did. It seems like it was dual problem the "row.ItemArray.SetValue" seems to not work with the foreach for whatever. Then it was the readonly problem as well (kinda weird that it took row[i] to give me an error to tell me what was going on). – chobo2 Feb 09 '12 at 22:49
1

That is the disadvantage with foreach loop, you can't modify content of the collection, because it is scoped to only inside the loop. You may need to use regular for loop. As per this microsoft document "The foreach statement is used to iterate through the collection to get the desired information, but should not be used to change the contents of the collection to avoid unpredictable side effects".

kosa
  • 65,990
  • 13
  • 130
  • 167
  • hmmm even if you have a for loop inside it going through another collection. It usually complains when you try to change a value within a foreach loop – chobo2 Feb 09 '12 at 22:24
  • Yes, change upper foreach to regular for-loop and try. – kosa Feb 09 '12 at 22:26
  • Nope this is not my problem. Something else is happening that is stopping it. – chobo2 Feb 09 '12 at 22:32
0

This will not Work as you are modifying an image of the data

ds.Tables[0].Rows[0].ItemArray[1] = “New Data”

This will work

ds.Tables[0].Rows[0].Item[1] = “New Data”;

Make sure you dont use itemarray, instead use item. This is for vb.net

Maddie
  • 11
  • 4
0

do you get the same result if you use

Debug.WriteLine("val: " + val + ", new: " + row.ItemArray[i].ToString());

try this

for (i=0; i< dt.Rows.Count ; i++)
{
  Debug.WriteLine("Start of Row");
  for (int j = 0; j < dt.Rows[i].ItemArray.Length; j++) 
  {
    string val = dt.Rows[i].ItemArray[j].ToString();
    dt.Rows[i].ItemArray[j] = "My New Value";

    Debug.WriteLine("val: {0}, new: {1}", val, dt.Rows[i].ItemArray[j].ToString());
  }
}
0

try setting readonly to false before making any changes

dt.Rows[i].ReadOnly = false

or cell only

dt.Rows[i].ItemArray[j].ReadOnly = false (not sure about this)