Remove Items in Entity Collection - c#

How to remove items in Entity Collection?
ex:
I have two entities that is related to each other
Employee and Reference
**Table: Employee**
EmployeeId(PK)
**Table: Reference**
ReferenceId(PK)
EmployeeId(FK)
Name
first I Initialize this:
Employee empCol = new Employee();
Reference refs = new Reference();
and then I save some data in the Entity Collection
refs.Name = "Sample";
empCol.References.Add(refs);
refs.Name = "Sample2";
empCol.References.Add(refs);
I want to remove the second element in the collection, how can I do that?
[0]= {Name = "Sample"}
[1]= {Name = "Sample2"}
I try this kind of code but it is not working, this code does not removing the second element in my Entity Collection, but it is not producing errors:
empCol.References.ToList().RemoveAt(1);

Dont assume how index is maintained inside by collection. Find the object first, and then remove it from collection
var ref = empCol.References.FirstOrDefault( r=> r.Name == "Sample");
if (ref != null)
empCol.References.Remove(ref);
If you want to remove by index, Find that index first.

I try to remove the object in the collection according to it's index in the collection and it work
var refs = empCols.References.ElementAt(1);
empCols.References.Remove(refs);

You can use all the List methods to remove items if you convert your EntityCollection into a List using toList(), for example
List<RotateArticle> articles = RotateArticle.GetDataByCategoryId(sm,currentArticle.MainCategory.Key).ToList();
and then
articles.Remove(articles[i]);
or
articles.RemoveRange(2, articles.Count - 1);

Related

What if I never create new object but keep adding the old object into the List by just updating it's value

In a for loop, instead of declaring a new object and add it to my List, I just update the value of the old object and every time keep adding this old object to my List, why after a few loops all List elements become the same
foreach (vg_ts_VesselCashflow_CashFlow_Entity item in cashflow)
{
var result = new VslMonthlyCashflow_Record();
result.CapitalCost = item.CapitalCost;
result.CharterRevenue = item.CharterRevenue;
result.Date = item.Period;
result.DryDock = item.DryDock;
resultList.Add(result);
}
if (resultList != null)
return resultList;
//Compared with this:
var result = new VslMonthlyCashflow_Record();
foreach (vg_ts_VesselCashflow_CashFlow_Entity item in cashflow)
{
result.CapitalCost = item.CapitalCost;
result.CharterRevenue = item.CharterRevenue;
result.Date = item.Period;
result.DryDock = item.DryDock;
resultList.Add(result);
}
I expect my resultList to be updated but if I keep using the old object, when it loops 123 times, all elements in the List will be the same.
List#Add doesn't copy the object or anything like that, it just keeps a reference to the object you passed to it. In the second snippet, you keep adding the same object to the list multiple times. Each modification you perform on the object is visible through all the references pointing to it, including the local result variable and all the elements of the list.

How to access a list with an index from a calling function

I am writing a c# console program.
I have a function that returns a list of objects.
e.g the following will return a list of objects.
p.getList();
If I already know the index of the object I want to reference from the list, then how to I access this?
For example I want to do the following which obviously is incorrect:
p.getList()[Index]
This would give me the item in the list at index.
To get around this I have done the following:
List<MyObject> mylist = p.getList();
mylist[Index];
but the above seems inefficient, to have to create a copy just to reference a value.
Any tips on how I can access?
Thanks.
If you don't want the list, but an item and you know the Index then
var item = p.getList()[Index];
syntax is perfectly correct. Please, notice, that List<T> is a reference type, that's why in case of
var list = p.getList(); // reference copy, not the collection cloning
var item = list[Index];
...
var otherItem = list[otherIndex];
the var list = p.getList(); adds a miniscule overhead: it's reference, not the entire collection is being copied.

How to preserve list values after linq operation?

I am querying azure table. After getting the data I am performing linq select operation and getting modified values.
But I want two lists one with old values and other with new values.
var oldUserEntities = userEntities.ToList();
var newUserEntities = userEntities.Select(i => { i.RowKey = dict[i.RowKey]; return i; }).ToList();
After this code if I verify values in oldUserEntites and newUserEntities, both having same modified values.
How to have old list and new list?
That's because the i in your projection is referencing the original item in oldUserEntities, then i.RowKey is modifying the original data.
Try this instead (assuming your entity is named UserEntity):
var oldUserEntities = userEntities.ToList();
var newUserEntities = userEntities.Select(i => new UserEntity
{
RowKey = dict[i.RowKey],
// rest of desired properties ...
}).ToList();
I'm not really sure what you're trying to do here, but this
> i => { i.RowKey = dict[i.RowKey]; return i }
is changing RowKey on every object in the list. The "return i" is then making a list containing the same, now modified, objects.
all this is really doing is
foreach(i in userEntities)
i.RowKey = dict[i.RowKey]
and then making a copy of the list

C# LINQ update item List<string>

I have problem with updating a single item under List<string> that matches a different string using LINQ. Let's say that I have a list of names and I want to check if name "John" already exists in my list. If yes, then replace "John" with "Anna".
Here is what I do:
var sItem = myList.First(n=> n == "John"); //I am 100% sure that John exists, that\s why I use .First
sItem = "Anna";
This is how it should work, but when I check my List (myList) after the process, the original item is still there (I can still see John, instead of Anna). I also tried to implement INotifyChanged on the List, but still no result.
What am I doing wrong?
If you need to update, use FindIndex:
int index = myList.FindIndex(n => n == "John");
myList[index] = "Anna";
You are assigning the result of linq query to a string variable. That is not the element of list but a variable that is also referencing the element of that list. Changing the value of variable sItem will define a new string that will be referenced by the sItem and the item in the list remains unchanged.
You can use FindIndex to get the index of element in the array and use it to refer to list element.
int index = myList.FindIndex(n => n == "John");
myList[index] = "Anna";
Searches for an element that matches the conditions defined by the
specified predicate, and returns the zero-based index of the first
occurrence within the entire List.
Edit
When one string variable is assigned to other. They both would be referencing the same string but when you assign a different string to second variable for instance then they both referencing different strings. See the following example from answer of Eric Lippert.
a----------------------Hello
Then you say that "b = a", which means attach another piece of string to the same thing that a is attached to:
a----------------------Hello
/
b---------------------
Then you say "now attach b to Hi"
a----------------------Hello
b----------------------Hi
int index = strList.FindIndex(n => n == "John");
if (index != -1)
{
strList[index] = "Anna";
}
This will ensure that if "John" does not exist in the list, the program does not crash.
It should work for you
List<string> list = new List<string>();
list.Add("Gandarez");
list.Add("Carlos");
var search = list.FirstOrDefault(l => l == "Carlos");
if (search != null)
{
var index = list.IndexOf("Carlos");
list.RemoveAt(index);
list.Insert(index, "Test");
}
int sItem = myList.FindIndex(x => x == "John");
myList[sItem] = "Anna";
The problem you are seeing is that System.String, while actually a reference type, acts like a value type. So, when you assign a new value to sItem you are replacing it, not changing it.
If you were using a true reference type, what you tried could have worked:
List<Person> myList = ....;
var sItem = myList.First(p=> p.Name == "John");
sItem.Name = "Anna";
(Assigning -- sItem = new Person("Anna"); -- would still fail the same way,)

Linq - get objects with a list property that does not contain values in another list

I feel like a complete idiot not being able to work this out myself.
I have a list of "Booking" objects called ExistingBookings. I also have an ObservableCollection of "Count" objects each of which has a "Bookings" property which is a list of "Booking" objects.
Using Linq, how do I select all the Count objects whose "Bookings" property does not contain any of the "Booking" objects in ExistingBookings?
i.e.
List<Booking> ExistingBookings = new List<Booking>();
ExistingBookings.Add(Booking1);
ExistingBookings.Add(Booking2);
Count1 = new Count();
Count1.Bookings.Add(Booking2);
Count1.Bookings.Add(Booking3);
Count2 = new Count();
Count1.Bookings.Add(Booking3);
Count1.Bookings.Add(Booking4);
List<Count> counts = new List<Count>();
counts.Add(Count1);
counts.Add(Count2);
I am expecting the output to be a list of Count objects containing only Count2, since neither of its Booking objects exist in ExistingBookings.
Please put me out of my misery :(
Assuming your Booking class implements equality and hash codes correctly you can use:
var result = counts.Where(c => !c.Bookings.Intersect(ExistingBookings).Any());
counts.Where(c => c.Bookings.All(b => !ExistingBookings.Contains(b)));

Categories

Resources