Updating data of a nested list with linq - c#

I have a user object that contains a nested list and i need to change the value of a element in the 3rd list and return the user object.
I want to do this with linq, below is the nested loop.
foreach (User itm in user)
{
if (itm.destinations!=null)
{
foreach (Models.Api.destinations.Destination dm in itm.destinations)
{
if (dm.destinationData != null)
{
foreach (Models.Api.destinations.DestinationData destData in dm.destinationData)
{
if (destData.type == "phone" & destData.data!="")
{
//i want to update the destData.data here .. something like
destData.data ='updated data';
}
}
}
}
}
}
I want the updated data to be available in the user object
can someone help me achieve this with the LINQ
Thanks in advance
Tarak

Try this:
foreach (var x in
(from itm in user
where itm.destinations!=null
from dm in itm.destinations
where dm.destinationData != null
from destData in dm.destinationData
where destData.type == "phone" & destData.data != ""
select new { itm, dm, destData }))
{
/* put your update code here. */
}
You didn't give us what the update code should look like or even the object models for us to work from.

Related

Iterating over two lists in c#

So i have a function that gets a list of students from a web service and also query the localdb for all the students in there. the data is placed in two different list. So i want to check to see if a new student already exists in the localdb List. if it does, update it and it if doesn't then add it. i unable to get it working . I am trying to perform this using LINQ, but i can't seem to get it working right. My LINQ skills are amateurish at best.
public async Task GetStudents()
{
String controllerName = "Students";
List<Students> newStudentData = await RunGetAsync<Students>(controllerName);
// get all the service types that already exists in the localStudent Db
List<Students> currentStudentData = db.Studentss.ToList();
foreach (Students existingStudents in currentStudentData)
{
foreach (Students newStudents in newStudentData)
{
IEnumerable<Students> selectStudents = from student in newStudentData // check if Students exist in the database
where student.Id == existingStudents.Id
select student;
if (selectStudents == null) // didn't find it, then add it
{
db.Students.Add(newStudents);
}
if (selectStudents != null) // found it , then update the informations
{
Students updatedStudents = new Students();
foreach (var field in selectStudents)
{
updatedStudents.FName = field.FName;
updatedStudents.LName = field.LName;
updatedStudents.ZipCode = field.ZipCode;
updatedStudents.AccessCode = field.AccessCode;
}
db.Entry(updatedStudents).State = System.Data.Entity.EntityState.Modified;
}
}
}
db.SaveChanges();
}
Thank you very much for your help.
you're looping more than you need :
foreach (Students newStudents in newStudentData)
{
var student = currentStudentData.FirstOrDefault(s => s.Id == newStudents.Id);
if(student == null)
{
//add
}
else
{
//update
}
}
with FirstOrDefault you can find out if it exists and get a reference to it at the same time, if it does.
You could use Intersect and Except like below:
//Find students that already exist to update
var updateStudents = currentStudentData.Intersect(newStudentData);
//Find new students to add
var addStudents = newStudentData.Except(currentStudentData);

Set a field in all the children of an item

I have an Item in sitecore lets say "AddressItem" that has some children. I want to edit a Field "IsMain" in all the child items.
I am using Foreach loop. Is there some better way to achieve this.
foreach (Sitecore.Data.Items.Item child in AddressItem.Children)
{
using (new SecurityDisabler())
{
child.Editing.BeginEdit();
child.Fields["IsMain"].Value = "0";
child.Editing.EndEdit();
}
}
Its probably faster to set the IsMain fields standard value to 0 then reset all items to that standard value. There is no function for that out of the box but the below code will do it.
This function is a little more robust then your requirement but its the code I have as is.
First you need a user with the correct permissions to replace: ElevatedUserAccount
Next get the list of items you would like to reset the values for then create a list of fields you wish to reset. In your case AddressItem.Children and IsMain.
Finally pass them into the below methods.
public void ResetFields(List<Item> items, List<string> fields)
{
if (items.Any() && fields.Any())
{
foreach (Item item in items)
{
ResetFieldsOnItem(item, fields);
}
}
}
public void ResetFieldsOnItem(Item item, List<string> fields)
{
if (item != null && fields.Any())
{
using (new Sitecore.Security.Accounts.UserSwitcher(ElevatedUserAccount, true))
{
item.Editing.BeginEdit();
foreach (string field in fields)
{
item.Fields[field].Reset();
}
item.Editing.EndEdit();
}
}
}

Find item from Viewbag.List

My controller code is as follows
ViewBag.Districts = (from a in _dbContext.DISTRICTS
select new ComboItem {
ID = a.DISTRICT_ID,
Name = a.DISTRICT_NAME
}
).ToList();
My Razor View code as follows
#foreach (var dist in ViewBag.Districts)
{
if (item.DISTRICT_ID == dist.ID)
{
#dist.Name
}
}
Is there a way I can find item in ViewBag.Districts like ViewBag.Districts.where(m=>m.ID==item.DISTRICT_ID.
or linq expression so that i can avoid looping.
Anyone helps me greatly appreciated.
Viewbag is dynamic so compiler won't be able to identify its actual Type, so you need explicit type cast like this to work with Enumerable methods:-
((IEnumerable<ComboItem>)ViewBag.Districts).Where(x => x.ID == item.DISTRICT_ID);
I am assuming you want to use this in your View, Also the foreach loop you have posted won't work without explicit casting:-
#foreach (var dist in (IEnumerable<ComboItem>)ViewBag.Districts)
{
if (item.DISTRICT_ID == dist.ID)
{
#dist.Name
}
}

How to get specific information from a session List

(List<Fruit>)Session["listSession"]
the session list is created in my home page.
and i would like to access information on another page
I would like to loop throw
if ((List<Fruit>)Session["listSession"].name == "apple ")
{
item.(access a method in my fruit class)
}else {
// do something else
}
\
List<Fruit> fruits = Session["listSession"] as List<Fruit>;
if(fruits != null)
{
foreach(Fruit fruit in fruits)
{
if(fruit.name=="apple")
fruit.Method();
else
//do something else
}
}
A couple of points here: you can just grab the instance from the session as a list and keep a reference to it, then you can check it is something (not null) and that it contains something which is also something (if nullable), before grabbing a reference of that and performing desired actions:
var fruitList = Session["listSession"] as List<Fruit>;
if (fruitList != null && fruitList.Count > 0)
{
var fruit = fruitList[0];
if (fruit != null && fruit.name == "apple ")
{
fruit.Consume();
}
}
That ought to help, though I'm sure you'll need to build on it to further your purpose.

Entity Framework: Best way to update related table

I have a structure like the following using EF:
An "Event" has many "Guests"
Let's say Event.Guests has 4 Guest elements, with the id's 1,2,3,4
I want to update the Event.Guests to have the guests with id's 3,4,5 (if Guest 5 doesn't exist I want to create it).
What's the most efficient way to remove the existing guests from Event and add the new one?
This is what I'm doing right now:
var newGuests = new List<Guest>();
var existingGuests = #event.Guests.ToList();
// GetNewGuestsIds will return the new guests list (3,4,5)
foreach (var guestId in GetNewGuestsIds())
{
Guest guest = existingGuests.FirstOrDefault(eg => eg.Id == guestId);
if (guest == null)
{
guest = db.Guests.CreateObject();
// fill guest data here
}
newGuests.Add(guest);
}
foreach (var existingGuest in existingGuests)
{
// Remove the existing element from the list to add
var removed = newGuests.RemoveAll(g => g.Id == existingGuest.Id);
if (removed == 0) // The existing host is not on the list to add, delete it
{
#event.EventHosts.Remove(existingGuest);
}
}
foreach (var guest in newGuests)
{
#event.Guests.Add(guest);
}
But I think this might be improved ... I just don't know how.
Thanks!
After some thought I came with this result which seems a lot better:
var existingGuests = #event.Guests.ToList();
// GetNewGuestsIds will return the new guests list (3,4,5)
foreach (var guestId in GetNewGuestsIds())
{
if (existingGuests.RemoveAll(g => g.Id == guestId) == 0)
{
guest = db.Guests.CreateObject();
// fill guest data here
#event.Guests.AddObject(guest);
}
}
existingGuests.ForEach(g => #event.Guests.Remove(g));
I hope this helps someone else.

Categories

Resources