I have some .NET 4.5 code:
var result = db.storedProcedure(param)
if (!result.Any()) { return; }
foreach (var entry in result)
{
// Some code...
}
At the foreach, an exception is throw:
The query results cannot be enumerated more than once.
How can I check if result is empty? I've also tried if (result.Count() == 0) and that also throws the same exception at the foreach loop. I've also tried foreach (var entry in result.ToList()) and that also throws the same exception.
I have tried following the suggestions here and here, with no luck.
I've also tried:
var result = db.storedProcedure(param)
if (!result.Any()) { return; }
var resultList = result.ToList();
foreach (var entry in resultList) {}
And I still get the same exception at that foreach loop as well.
There must be some way to easily check if a Linq result set is empty. What am I doing wrong?
Just put the result into a List before iterating:
var result = db.storedProcedure(param).ToList();
if (result.Count == 0) { return; }
Why do you even to make that check at all? Your loop won't even run at all if there's nothing in result. Just have this:
var result = db.storedProcedure(param)
foreach (var entry in result)
{
// Some code...
}
return;
Related
I am trying to modify some values within the value of the List collection List<DataClass>. The value which I am trying to modify listValues[i].destinationValue and listValues[i].sourceKey which is also a list collection. When I am trying to add another value to the collection it works using foreach loop. But when it goes to next value in the foreach loop value it stops and I get the error: System.InvalidOperationException: 'Collection was modified;.
foreach (var listValue in listValues)
{
if (listValue.hostName == data[4] && listValue.description == data[3] && listValue.ruleName == data[2])
{
var i = listValues.FindIndex(x => x.hostName.Equals(listValue.hostName));
listValues[i].destinationValue.Add(data[0]);
listValues[i].sourceKey.Add(data[1]);
}
else
{
listValues.Add(docValueModelClass);
}
}
if (listValues.Count == 0)
{
listValues.Add(docValueModelClass);
}
Can you please suggest, how can I overcome this?
You can't edit same list or same enumerating list inside foreach loop, Because we using same list for enumerable.
just use for loop to edit - It works.
I have the following code where I am checking if some elements are not matching in my dictionary then I want to remove the unmatching elements from the local item. The problem is, When a value is removed from the collection, for some reason it also modifies the parental structure.
My other problem is, for example if I have list as "A","B","B", using the Except is only giving me the single B but not the other. Please help.
public void AddLogs(IEnumerable<ReportGenerationTypes> subElements)
{
var changeDetails = new Dictionary<AuditSaveHeader, List<string>>();
List<string> AuditableItems = null;
List<string> subItems = new List<string>();
foreach (var item in subElements)
{
subItems.Add(item.ToString());
}
foreach (var item in auditLogData?.AuditHeaders)
{
if (!changeDetails.ContainsKey(item))
{
changeDetails.Add(item, null);
}
AuditableItems = new List<string>();
foreach (var inner in item.AuditChangeValues)
{
AuditableItems.Add(inner.Auditable.ToString());
}
changeDetails[item] = AuditableItems;
}
for (int i = 0; i < changeDetails.Count; i++)
{
var result = kp.Value.Except(subItems);
Auditable AuditItem = Auditable.Unassigned;
//I think the problem lies with the below code not sure.
if (result != null && result.Count() > 0)
{
foreach (var item in result)
{
Enum.TryParse(item, out AuditItem);
var itemToRemove = kp.Key.AuditChangeValues.Where(x => x.Auditable == AuditItem).FirstOrDefault();
//The following line effects the AuditChangeValues object and not just my dictionary.
kp.Key.AuditChangeValues.Remove(itemToRemove);
}
}
}
}
Promoting my comment to answer:
You are using some vars that are not shown, like kp, auditLogData, etc. and overall is not clear what you want to achieve.
Anyway I agree the problem is you are editing the reference to an object. You could try cloning the objects, etc. But without really understanding the code is hard to tell.
I have a list of organizations attached to the users that need to be removed and a new set added. I am using entity framework
var user = db.Users.Find(model.Id);
foreach (var item in user.Organizations)
{
user.Organizations.Remove(item);
}
var userOrgs = db.Organizations.Where(o => model.Organizations.Contains(o.ID)).ToList();
foreach (var item in userOrgs)
{
user.Organizations.Add(item);
}
db.SaveChanges();
I end up getting an exception {"Collection was modified; enumeration operation may not execute."} when i try to remove the second item. Is there an alternate approach?
Try to use ToList in your first foreach:
var user = db.Users.Find(model.Id);
foreach (var item in user.Organizations.ToList())
{
user.Organizations.Remove(item);
}
I currently have a snippet of code that will act upon every user found in Active Directory and as I was looking at it I started to wonder if it is better to have the method call done before the foreach loop or if it is ok the way it is. I have tested using principalSearcher.FindAll()) both inside and out of the loop and can't notice a difference but then there is not really a large enough data set to see one, so I am wondering about this more from a best practice situation.
foreach (var user in principalSearcher.FindAll())
{
var employeeID = db.Employees
.Where(employee => employee.ADUserName == user.SamAccountName && employee.EndDate == null)
.Select(employee => employee.ID)
.FirstOrDefault();
if (employeeID > 0)
{
var updatedEmployee = db.Employees.Find(employeeID);
updatedEmployee.EndDate = DateTime.Today;
db.SaveChanges();
}
}
Note: principalSearcher is of type System.DirectoryServices.AccountManagement.PrincipalSearcher
The foreach will get compiled to (roughly)
//begin decomposition of foreach (var user in principalSearcher.FindAll())
var temp = principalSearcher.FindAll();
var enum = temp.GetEnumerator();
while(enum.MoveNext())
{
var user = enum.Current;
// body of foreach block
}
// end decomposition
versus
// local variable outside of foreach
var allPrincipals = principalSearcher.FindAll();
//begin decomposition of foreach (var user in allPrincipals)
var enum = allPrincipals.GetEnumerator();
while(enum.MoveNext())
{
var user = enum.Current;
// body of foreach block
}
// end decomposition
So whether you declare a variable outside of the foreach and use it or not makes no practical difference.
*Note that I do not include other artifacts like try/finally or casting/boxing since they are not germane to the question.
datacontextclass dc=new datacontextclass ();
var news= dc.GetNewsCompany(Int64.Parse ( _idCompany));
if (news.GetEnumerator().MoveNext())
{
foreach (var item in news)
{
drpListNews.Items.Add(item.Title);
}
}
return error:{"The query results cannot be enumerated more than once."}
how can check result != null in LINQ;
Using an enumerator wildly is a bad idea - for example, it needs disposing - which you haven't done (this could lead to a SqlDataReader being left open - not good). In this case, just enumerate it. If there aren't any records, that will be trivial:
if (news!=null)
{
foreach (var item in news)
{
drpListNews.Items.Add(item.Title);
}
}
If you need the data twice, put it in a list:
var news = (blah).ToList();
You are creating the enumerator twice. The first is by calling news.GetEnumerator(), the second one happens behind the scenes in the foreach loop. The first "check" that you make with the call to MoveNext does not seem necessary (you will not go into the foreach unless there are items to iterate over), so just skip the if statement wrapping the loop:
datacontextclass dc = new datacontextclass();
var news = dc.GetNewsCompany(Int64.Parse(_idCompany));
foreach (var item in news)
{
drpListNews.Items.Add(item.Title);
}
Change the second line of your code to
var news= dc.GetNewsCompany(Int64.Parse ( _idCompany)).toList();
it shall remove the issue.