foreach in foreach list c# - c#

The GalleryDetail.Id is 148 when it enters the first foreach loop, and the GalleryDetail.Id is 148 when it enters the second foreach loop. But it does not enter the first foreach loop again. It continues from the second. How do I get it to re-enter the first loop here?
NOTE: I do not have direct access from the GalleryDetail.Id request.
var detailList = await _repo.GalleryDetail.GetAllAsync();
foreach (var item in mapped.GalleryDetails)
{
foreach (var item2 in detailList)
{
if (item.Id != item2.Id)
{
var mapped3 = _mapper.Map<GalleryDetails>(item2);
await _repo.GalleryDetail.DeleteAsync(mapped3);
}
}
}

It's not necessary to use 2 loop here, you can use LinQ instead. And you should not leave async Delete inside foreach loop, because it will connect to you database mutiple time. Example:
var detailList = await _repo.GalleryDetail.GetAllAsync();
//Map the whole list
var detailListMapped = _mapper.Map<List<GalleryDetails>>(detailList);
//Use LinQ to find database items not in request
var deletedList = detailListMapped.Where(x => !mapped.GalleryDetails.Any(y => y.Id == x.Id)).ToList();
//Entity Framework have RemoveRange function, you should use it here
await _repo.GalleryDetail.RemoveRangeAsync(deletedList );

Related

How to find if item in one Observable Collection?

I would like to request you to help me with this problem. I have an Observable Collection that stores favourites and I load items to another Observable Collection, so, what I want is for the new items which have unique IDs to be checked against Favourites Observable Collection in an efficient way as I feel what I am doing is not good enough.
What I am currently doing is as follows:
foreach (var item in AllItems)
{
if (Watchlist.Fav.Count != 0)
{
if (Watchlist.Fav.Any(s => s.Id == item.Id)))
{
Watchlist.Fav.Remove(Watchlist.Fav.SingleOrDefault(i => i.Id == item.Id));
Watchlist.Fav.Add(item);
item.IsFavorite = true;
ItmesCollection.Add(item);
}
}
}
Could someone please help me make this better?
Cheers guys!
Since OP is asking a better syntax of current working code. Here is a try:
foreach (var item in AllItems)
{
// no need check Watchlist.Fav.Count, because .Any duplicates
// store matchingFav in variable so no need query twice
var matchingFav = Watchlist.Fav.SingleOrDefault(s => s.Id == item.Id)));
if (matchingFav != null)
{
matchingFav.IsFavorite = true;
// where is ItemsCollection from? background not clear, so no change
ItemsCollection.Add(item);
}
}
If the last statement is not relavant, syntax can be even shorter:
var ids = new HashSet<int>(AllItems.Select(x => x.Id));
foreach (var matchingFav in Watchlist.Fav
.Where(x => ids.Contains(x.Id)))
{
matchingFav.IsFavorite = true;
}

Replace foreach with lambda while updating list

I want to update vmlist by geting values from vlist without using any foreach loop.
For now I am just doing this with foreach loop, but I want to replace this foreach with LINQ
foreach (var item in vlist){
vmlist.Where(list => list.SId==item.SId && list.ParameterId==item.ParameterId && list.WId==item.WId)
.Select(li => { li.Value = item.Value; return li; }).ToList();
}
Your current approach is very inefficient - it's O(N * M) and it creates a list on each iteration.
Using a join would be more efficient - I would still use a foreach loop, but separate the querying part from the update part:
var pairsToUpdate = from original in vmlist
join item in vlist
on new { original.SId, original.ParameterId, original.WId }
equals new { item.SId, item.ParameterId, item.WId }
select new { original, item };
foreach (var pair in pairsToUpdate)
{
pair.original.Value = pair.item.Value;
}
No abuse of Select with side-effects
No extra lists created for no good reason
More efficient selection of items to update

Avoid Interception de InvalidOperationException when modifing a collection

I have this code to modify the categorie list foreach opened Form
var lst = Application.OpenForms.OfType<FrmProduit>();
foreach (var item in lst)
{
item.getCategorie(Categories.getLastCategorieId());
}
Well, the first loop is ok, but then second loop I have the InvalidOperationExcetion
Any help please
Try using the List<T> ForEach method as follows:
Application.OpenForms.OfType<FrmProduit>()
.ToList()
.ForEach(i => i.getCategorie(Categories.getLastCategorieId()));
This will not throw the error - but if the 'getCategorie' method has a return value, you might want to do something with it. If that's the case, you need:
Application.OpenForms.OfType<FrmProduit>()
.ToList()
.ForEach(i =>
{
var retVal = i.getCategorie(Categories.getLastCategorieId());
// do something with retVal here...
});

Why values not assigned in IEnumerable?

I parse some data
var result = xml.Descendants("record").Select(x => new F130Account
{
Account = x.Descendants("Account").First().Value,
});
Then I try to some update
foreach (var item in result)
item.Quantity = 1;
After this I have result.Sum(a => a.Quantity) is zero... Why?
That's because your result collection is evaluated again each time you start enumerating it, so Sum runs on new set of F130Account objects, different then foreach loop. That's how LINQ and it's laziness works.
Initialize results to List<F130Account> first:
var result = xml.Descendants("record").Select(x => new F130Account
{
Account = x.Descendants("Account").First().Value,
}).ToList();
And after that both foreach and Sum will run on the same collection of objects.

Modifying properties in object with LINQ and functions Lamba

Friends,
I know how to deploy and retrieve a single element in LINQ, but how can I do to change all the properties in a list. In the line below, I can only modify a record, I would modify several.
_ListaAcaoMenuInfo.Where(p => p.Id_acao == id).FirstOrDefault().Id_menu = 0;
Thanks
Use the ForEach function of a List...
_ListaAcaoMenuInfo.Where(p => p.Id_acao == id).ToList().ForEach(item=>item.Id_menu=0);
You wouldn't want to. LINQ is not to be used for side effects. There's a foreach loop for that.
foreach (var x in collection.where(x => x.Foo = "Blah"))
x.Foo = "Bar";
Use foreach:
var l = _ListaAcaoMenuInfo.Where(p => p.Id_acao == id).ToList();
foreach (Thing i in l)
{
i.Id_menu = 0;
//now use your Context object to save back to the database
}

Categories