Datatable reset during foreach loop - foreach

I'm currently stuck on an issue that I cannot understand:
The following code produce a Datatable ("outDT") in order to populate a gridview later on. The datatable is build using rows of others datatables issued from various SQL quieres (those "get" function that return also Datatable).
The issue come when I call the "getAverage" method. Right after the call, the "pcDT" Datatable is nullified and cause a further "Collection was modified; enumeration operation might not execute." error on next loop.
I never modified a single row of the "pcDT" Datatable in the foreach loop, nor in the problematic "getAverage" method.
public DataTable getReportTable(int idClient)
{
Object thisLock = new Object();
DataTable outDT = new DataTable();
outDT.Columns.Add("PC Name");
DataTable pcDT = getPCNames(idClient);
*foreach (DataRow pcRow in pcDT.Rows)*
{
DataRow outRow = outDT.NewRow();
outRow["PC Name"] = pcRow["Name"];
**DataTable collectedDT = getAverage((int)pcRow["idPC"]);**
foreach (DataRow dataRow in collectedDT.Rows)
{
outDT.Columns.Add(dataRow["name"].ToString());
outRow[dataRow["name"].ToString()] = dataRow["AVG(MeasurePoint.dataValue)"];
}
outDT.Rows.Add(outRow);
}
return outDT;
}
(*)This foreach cause the famous "Collection was modified; enumeration operation might not execute." error
(**) And here his the method call that reset the "pcDT" Datatable. This function simply call a mySQL queries and retrieve a Datatable.

It's ok, I've found my mistake. It was in the class that manage basic SQLQueries; I used a Datatable instance that is linked to the class and not to the method, so when I recall a method that used this instance, I lost previous filled Datatable...
My bad :/

Related

Insertion on Asp.Net Mvc Failed

On my asp.net mvc project, the table data will be displayed on a grid view using Index Method.
After doing Insertion, it would redirect to Index using RedirectToAction. But for the First time, the new row is getting added to the grid. When tried second time, the insertion is not possible.
But if i reload the page using browser reload again, for the first time only insertion takes place. Please help me to resolve this issue.
When I tried to debug, "the process has been changed since the last step" takes place. So, the values during the first debug also coming for insertion on second time which break the operation. Give Solution pls..
public ActionResult Index()
{
X_DEVEntities Entity = new X_DEVEntities();
var outPut=Entity.Model.ToList();
return View(outPut);
}
public ActionResult Insert(Model modelData)
{
X_DEVEntities Entity = new X_DEVEntities();
modelData.create_user_id = "ty";
modelData.last_mod_dtm = DateTime.Now;
modelData.last_mod_user_id = "gdf";
Entity.Model.Add(modelData);
Entity.SaveChanges();
return RedirectToAction("Index");
}
On second insertion you are getting error because on each insertion you'll have same create_user_id and last_mod_user_id based upon the your Insert method you posted.
I'm guessing it should be something like this
public ActionResult Insert(Model modelData)
{
X_DEVEntities Entity = new X_DEVEntities();//try not to do this in your Insert method, rather have a constructer where you place this instantiation.
Entity.yourTableName.UserId=modelData.create_user_id;//(UserId should be the field where you want to place the username you get from the view)
modelData.last_mod_dtm = DateTime.Now;
Entity.yourTableName.LastModUserId=modelData.last_mod_user_id;//again LastModUserId is the field where you want to save your modelData.last_mod_user_id in table.
Entity.Model.Add(modelData);
Entity.SaveChanges();
return RedirectToAction("Index");
}

Why is my code not able to update the database?

I am having trouble saving my entities after updating them. I can add new entities like this: add(student); but if I tried this:
if (ModelState.IsValid)
{
db.Entry(student).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("someView");
}
I get this error message:
System.Data.Entity.Infrastructure.DbUpdateConcurrencyException was unhandled by user code
Message=Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or
deleted since entities were loaded. Refresh ObjectStateManager
entries.
Here’s my controller method:
[HttpPost]
public ActionResult ClassAttendance(InstructorIndexData viewModel, FormCollection frmcol)
{
var instructorData = new InstructorIndexData();
string[] AllFstMNames = frmcol["item.Student.FirstMidName"].Split(',');
string[] AllLstNames = frmcol["item.Student.LastName"].Split(',');
string[] AllAddresses = frmcol["item.Student.Address"].Split(',');
string[] AllEnrollmentDates = frmcol["item.Student.EnrollmentDate"].Split(',');
//more of the same code…
var student = new Student();
var enrollment = new Enrollment();
for ( int i = 0; i < AllFstMNames.Count(); i++)
{
student.FirstMidName = AllFstMNames[i];
student.LastName = AllLstNames[i];
student.Address = AllAddresses[i];
student.EnrollmentDate = Convert.ToDateTime(AllEnrollmentDates[i]);
if (!string.IsNullOrEmpty(frmcol["item.Grade"]))
{
enrollment.Grade = Convert.ToInt32(AllGrades[i]);
}
enrollment.StudentID = Convert.ToInt32(AllStudentIds[i]);
enrollment.attendanceCode = Convert.ToInt32(AllAttendanceCodes[i]);
enrollment.classDays = AllclassDays[i];
enrollment.CourseID = Convert.ToInt32 (AllCourseIds[i]);
//update rows
}
if (ModelState.IsValid)
{
db.Entry(student).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("someView");
}
Can you help me with just being able to update values in the database?
While I was looking at the code here, my initial thought is that it doesn't seem quite right to have a for loop that updates the student and enrollment objects multiple times and then to have only one call to db.SaveChanges outside the loop. This is concerning because only the last iteration of the for loop will be applied when the data is saved to the database. (You have a comment to "update rows" at the end of the for loop - perhaps some code is missing or misplaced?)
Then, I started thinking about why it would be necessary to manually set the Entry(...).State property. Wouldn't the db automatically know that an object is modified and needs to be saved? That lead me to this question: Where is db defined? What technology stack is being used there?
Finally, after making an assumption that the db object might work something like the MS LINQ-to-SQL feature, I noticed that the the student object is newly instantiated before the for loop. This is fine for inserting new data, but if you are wanting to update existing data, I believe you need to first get a copy of the object from the database and then update the properties. This allows the db object to monitor the changes (again, assuming that it has this capability). (If this is not the case, then it leads me to wonder how the db will know which record in the database to update since you are not setting anything that appears to be a primary key, such as StudentId, on the student object in the loop.)

.Net Entity Framework ObjectContext error

I have method with code:
using (var cc = new MyDBContext())
{
var myList = (from user in cc.Users
where user.UserGroup.Name == "smth"
orderby user.ID ascending
select user);
if (startIndex != null)
return View(myList.Skip((int)startIndex).Take(50));
else
return View(myList);
}
In view I catch exception The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
Some people says that .ToList() must solve problem, but it throws an exception with myList.ToList() too. What is my problem?
P.S. in debug mode I have exception at #item.FullName in view, but if I move mouse on FullName property I can see correct value.
Sorry for my bad english.
Take the "return View()" statements outside of the "using" block completely. That will ensure you have retrieved the complete data sets before your DbContext object is disposed. Like this:
using (var cc = new MyDBContext())
{
var myList = (linq).ToList();
}
return View(myList);
I'm pretty sure the problem is that you are returning an IEnumerable to the View, which means the items haven't actually been retrieved yet. But when you return the object to your View, the DbContext is getting disposed before the view has a chance to retrieve the rows.
The problem was in lazy loaded sub property of User entity. I add to link statement Include("PropName") and it works good.

Saving nested objects with linq to entities

I have a UI that presents a number of checkboxes to the user, and for each one that is checked, I need to create an entry in a mapping table.
LookupTable <- MapTable -> DataTable
I have a custom binder for DataTable, but can't figure out how to get it to create the MapTable objects.
Is this possible? Using asp.net MVC 1.0 and LINQ to Entities.
You need to take care of two steps. (1) Add the newly selected values and (2) remove the unselected values. You'll need a method like this in your LookupTable class.
public void SynchronizeDataTables(IEnumerable<DataTable> dataTables)
{
// get the current data tables. call ToList() to force and enumeration.
// without the ToList(), you'll get a "Sequence Changed during Enumeration"
// error
var currentDataTables = MapTable.Select(m => m.DataTable).ToList();
// if the table is selected, but not in the data store add it.
foreach (var dataTable in dataTables)
{
if (!currentDataTables.Contains(dataTable))
{
MapTables.Add(new MapTable { DataTable = dataTable });
}
}
// if the table is in the data store, but not selected, then remove it.
foreach (var dataTable in currentDataTables)
{
if (!dataTables.Contains(dataTable))
{
MapTables.Remove(dataTable);
}
}
}
Edit: When I did this, I was using LINQ-to-SQL, and I cycled through just the selected ID's, instead of the entire object. This is more complicated because LINQ-to-Entities creates slightly different objects than LINQ-to-SQL, because it doesn't expose the FK identity. Slight modification follows:
public void SynchronizeDataTables(IEnumerable<int> dataTableIds)
{
// get the current data tables. call ToList() to force and enumeration.
// without the ToList(), you'll get a "Sequence Changed during Enumeration"
// error
var currentDataTableIds = MapTable.Select(m => m.DataTable.Id).ToList();
// if the table is selected, but not in the data store add it.
foreach (var dataTableId in dataTableIds)
{
if (!currentDataTableIds.Contains(dataTableId))
{
var dataTable = ???; // some method to fetch data table with ID = dataTableId
MapTables.Add(new MapTable { DataTable = dataTable });
}
}
// if the table is in the data store, but not selected, then remove it.
foreach (var dataTable in currentDataTableIds )
{
if (!dataTableIds.Contains(dataTableId ))
{
var dataTable = ???; // some method to fetch data table with ID = dataTableId
MapTables.Remove(dataTable);
}
}
}

NHibernate Concurrency Issue

Over the weekend I realized that an application I'm working on which uses NHibernate as an ORM to a sqlite database has a concurrency issue.
I'm essentially looping through a collection in javascript and executing the following:
var item = new Item();
item.id = 1;
item.name = 2;
$.post("Item/Save", $.toJSON(item), function(data, testStatus) {
/*User can be notified that the item was saved successfully*/
}, "text");
And my server code looks like this:
public ActionResult Save()
{
string json = Request.Form[0];
var serializer = new DataContractJsonSerializer(typeof(JsonItem));
var memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(json));
JsonItem item = (JsonItem)serializer.ReadObject(memoryStream);
memoryStream.Close();
SaveItem(item);
return Content("success");
}
The concurrency issue obviously occurs in the loop calling Save() for each element iterated, but I'm not sure how to accommodate for and prevent this. Any advice is appreciated.
What is the concurrency issue?
I didn't understand your problem with concurrency.
Comment: if you iterate the collection, AND in the postback you reload the window... hmmm... there is a potential problem here. The first postback will throw away any pending work, refreshing completely the page.
Suggestion: don't iterate, send the complete collection in one Ajax call.

Resources