Modifying properties in object with LINQ and functions Lamba - c#

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
}

Related

How to create a list of Guid (Guid []) from a list of objects with linq?

I have a code :
{
int i = 0;
Guid[] ids = new Guid[clientCertifications.Count()];
foreach (Certification certif in clientCertifications)
{
ids[i] = certif.Id;
i++;
}
return listOffices.GroupBy(lo => lo.pk_Office)
.Select(loG => loG.First()
.MapOfficeToModel(
loG.Where(g => g.FK_Guid.In(ids)).Select(g => g.FK_Guid).ToCertifications(clientCertifications)
));
}
I would like to know if it is possible to obtain the list "ids" using a select or other word of linq? In the example I use a loop for and foreach, but I think we can do shorter no? In the line :
loG.Where(g => g.FK_Guid.In(***here something like: clientCertifications.Select(o => o.Id ... )*** ids)).Select(g => g.FK_Guid).ToCertifications(clientCertifications)`
This piece of your code:
int i = 0;
Guid[] ids = new Guid[clientCertifications.Count()];
foreach (Certification certif in clientCertifications)
{
ids[i] = certif.Id;
i++;
}
is basically the complicated version of:
var ids = clientCertifications.Select(certif => certif.Id).ToArray();
And you should be able to put clientCertifications.Select(certif => certif.Id).ToArray() wherever you would have used the variable ids if it's plain LinQ. If you have a provider for LinQ that does transformations (for example to database statements) that may not work and you may need the temporary variable. But then, if you do use such a provider, there might be an entirely different and maybe better way.

iterate through a list of items inside lambda expression

I'm trying to loop through a list in a lambda expression.
Here is my code I though i could do.
var table = shipment.ShipmentItems.ToList();
for (int i = 0; i <= table.Count; i++)
{
shippedItems = shipment.Order.OrderItems.Where(x => x.Id != table[0].OrderItemId); ;
}
I need to use each index in table, table[1].OrderItemId, table[0].OrderItemId etc
Whats the best way to do this.
Cheers
is the end result all of the order items that are not in the shipment items list?
var orderItemIds = shipment.ShipmentItems.Select(si => si.OrderItemId).ToList();
var shippedItems = shipment.Order.OrderItems.Where(oi => !orderItemIds.Contains(oi.Id));

Coverting a foreach loop containing an if statement into linq method syntax in C#

I am trying to convert this to a linq statement with method syntax. I am not sure how to do it when teh foreach loop has an if statement. In the code below, MyMethodToConvert replaces the string "Tomorrow" to DateTime.Now
foreach (var data in MyCollection)
{
if (data.DeliveryDate.Equals("Tomorrow"))
{
data.DeliveryDate = MyMethodToConvert(DeliveryDate);
}
}
I tried this, t didn't work
MyCollection = MyCollection.Select(a =>
{
a.DeliveryDate.Equals("Tomorrow")
? MyMethodToConvert(DeliveryDate)
: a.DeliveryDate)
;
return a;
}).ToList();
But it didn't work.
Go only this far:
foreach (var data in MyCollection.Where(x => x.DeliveryDate.Equals("Tomorrow")))
{
data.DeliveryDate = MyMethodToConvert(DeliveryDate);
}
If the compile-time type of x.DeliveryDate is string, prefer:
foreach (var data in MyCollection.Where(x => x.DeliveryDate == "Tomorrow"))
{
data.DeliveryDate = MyMethodToConvert(DeliveryDate);
}
You could use this:
MyCollection = MyCollection.Select(data =>
{
if (data.DeliveryDate.Equals("Tomorrow"))
data.DeliveryDate = MyMethodToConvert(DeliveryDate);
return data;
}).ToList();
Or, if you don't want any Semicolons in your code (I'll assume that you have a class named Delivery with a constructor just for the DeliveryDate):
MyCollection = MyCollection.Select(data => data.DeliveryDate.Equals("Tomorrow")
? new Delivery(MyMethodToConvert(DeliveryDate))
: data).ToList();
However, I wouldn't suggest to use Linq in here. The only little bit useful use of Linq would be what Jeppe Stig Nielsen suggested.
How about this:
MyCollection.Where(d => d.DeliveryDate.Equals("Tomorrow"))
.ToList()
.ForEach(d => d.DeliveryDate = MyMethodToConvert(DeliveryDate));

Filter across 2 lists using LINQ

I have two lists:
a. requestedAmenities
b. units with amenities.
I want to filter those units that have any one of the "requested amenities".
I have tried to achieve the same result using foreach loops but I believe it should be much easier using LINQ. Can someone please help\advice?
UnitAmenities unitSearchRequestAmenities = unitSearchRequest.Amenities;
var exactMatchApartmentsFilteredByAmenities= new Units();
IEnumerable<string> requestAmenitiesIds = unitSearchRequestAmenities.Select(element => element.ID);
foreach (var unitCounter in ExactMatchApartments)
{
IEnumerable<string> unitAmenities = unitCounter.Amenities.Select(element => element.ID);
foreach (var requestAmenityId in requestAmenitiesIds)
{
foreach (var unitAmenity in unitAmenities)
{
if (requestAmenityId == unitAmenity)
{
exactMatchApartmentsFilteredByAmenities.Add(unitCounter);
//break to the outmost foreach loop
}
}
}
}
You could filter based on compliance with an Intersect rule
var matchedAmenities = ExactMatchApartments.Where(ema => ema.Amenities
.Any(x => unitSearchRequestAmenities
.Count(y => y.ID == x.ID) == 1));
exactMatchApartmentsFilteredByAmenities.AddRange(matchedAmenities);
This is a somewhat "custom" Intersect given that the default LINQ Intersect extension doesn't support lambda expressions.
It's hard to tell from your types, but I think the following should do the trick
from unit in ExactMatchApartments
from amenity in unit.Amenities
join requestedAmenity in unitSearchRequestAmenities
on amenity.ID equals requestedAmenity.ID
select unit
This is a case where a query expression is both easier to read and understand as opposed to dot notation.
Thanks Jason, I believe it must be Intersect not Except.I have changed the code to the following:
var amenities = unitSearchRequest.Amenities;
if (amenities.Count > 0)
{
//filter the unit's amenities's id's with the search request amenities's ID's.
var exactMatchApartmentsFilteredByAmenities= new Units();
var requestAmenitiesIds = amenities.Select(element => element.ID);
foreach (var unitCounter in ExactMatchApartments)
{
var unitAmenities = unitCounter.Amenities.Select(element => element.ID);
var intersect =unitAmenities.Intersect(requestAmenitiesIds);
if (intersect.Any())
{
exactMatchApartmentsFilteredByAmenities.Add(unitCounter);
break;
}
}
}
I will test the code and update here my results.

Linq query referencing objects and a string array

I am having some trouble in converting the following code to use LINQ.
int occurs = 0;
foreach (string j in items)
{
if (!string.IsNullOrEmpty(j))
{
WorkflowModule tempWM = new WorkflowModule(j);
if (tempWM.StateID == item.StateID)
{
occurs++;
}
}
}
return occurs;
So far, I have:-
var lstItems = (from lstItem in items
where !string.IsNullOrEmpty(lstItem)
let objWorkflowModule = new WorkflowModule(lstItem)
select new
{
tempWM = objWorkflowModule.StateID
}).Where(item.StateID == tempWM));
return lstItems.Count();
but intellisense is not liking the line '.Where(item.StateID == tempWM))'
Can anyone help me achieve this?
Thanks.
When you use the method syntax, you need to use a lambda on the Where operator:
...
}).Where(x => x.tempWM == item.StateID));
In other words, you need to "declare" the variable x which holds the result of the previous part of the query.
It doesn't look like item is initialized anywhere in your statement.
Here's how I'd do this
var lstItems = from lstItem in items
where !string.IsNullOrEmpty(lstItem)
let objWorkflowModule = new WorkflowModule(lstItem)
select objWorkflowModule.StateID;
return lstItems.Count(t=> t == item.StateID);
I'm assuming item is a variable defined outside of the original code you submitted. Basically you don't need to create the anonymous class in the query and you can put the predicate in you're Where into Count instead. But as others have said the main issue is that you need to express your predicate as a lambda.

Categories