I have a method which return a List of Class object.
After getting the list I want to check whether a specific entry exists or not
Below is my query
var myList = GetMethod()
if(myList != null && myList.Select(x => x.Id=='MyId').Any())
{
// Do work
}
If the mylist is not null then myList.Select(x => x.Id=='MyId').Any() is always returning true even if a matching entry is not there.
Can someone help me in this?
That is because you need a Where over a Select:
if(myList != null && myList.Where(x => x.Id=='MyId').Any())
Now the Select ends up with an enumerable of booleans... Some are true, some are false.
You could simply that to:
if(myList != null && myList.Any(x => x.Id=='MyId'))
Select returns an IEnumerable of booleans whether the condition was true for each item or not. So, Any() is always returning true as long as there are items in your list.
Just use:
myList?.Any(x => x.Id == "MyId") == true;
Note that I don't like boolean comparisons like == true but this is for the null-check with ?. upfront.
Related
i have this linq query. I need to look for any good alternative if possible for this higlighted lambda expression inside Where condition. I was thinking to use coalesce condition ( ?? ) but couldnt make a query.
.Where(p => p.Property== null ? true : p.Property.SubPropertyList.Contains(Item))
So, I want to get those items from list which has a property null or if not null then satisfies a condition ( Contains() )
You need to create a predicate.
A function that will return true of false.
In you case:
.Where(***p => p.PalletMission == null || p.PalletMission.Destinations.Contains(currentGtpOrder.GtpStation.Node))
var result = list
.Where(p =>p.Property == null || p.Property?.SubPropertyList.Contains(1) == true);
I have this GroupJoin:
var groupjoin = cData.GroupJoin(
aData,
c => c.Id,
a => a.Id,
(c, joined) => new { c, a = joined.DefaultIfEmpty() })
.ToList();
In my test data, there are NO matches. So, I have this code:
var difference = groupjoin.FirstOrDefault(g =>
g.a == null);
I was expecting difference to be an anonymous object with a "c" property that was an object from cData, and an "a" property that was null.
However, g.a == null is never true, so FirstOrDefault gives me a null for difference. g.a is, in fact, a DefaultIfEmptyIterator and g.a.ToList() gives me a count of 1, and g.a.ToList[0] == null is true.
What have I done wrong here?
That's how DefaultIfEmpty works. This method returns a collection with one element (type parameter's default) if the collection is empty, not null.
So in your case, if there are no matches, joined.DefaultIfEmpty() will return a collection with just one element, that is null for reference types.
If you want null when joined is empty try something like this:
joined.Any() ? joined : null
You can read more about DefaultIfEmpty here.
In the code below I am trying to get the null, empty string, and source components out of a List. I have not tested this code yet but my intuition tells me it will break when filtering the List for source and empty string if it comes by a null value.
I tried to extract the null values first, but I am still filtering the base List. How can I re-write this code to accomplish what I am trying to do in the best way?
List<LineItem> nullList=itemsList.Where(s => s[Constants.ProductSource] == null)
.ToList();
NALineItems = itemsList.Where(s => s[Constants.ProductSource] == source
|| s[Constants.ProductSource] == String.Empty)
.ToList();
NALineItems = nullList.Union(NALineItems).ToList();
s[Constants.ProductSource] is an attachment property to Microsoft ECommerce PurchaseOrder object. Its basically another property of an object.
Based on "I am trying to get the null, empty string, and source components out of a List" I assume you mean you want a list with these 3 specific values.
var allItems = itemsList
.Where(s => string.IsNullOrEmpty(s[Constants.ProductSource])
|| s[Constants.ProductSource] == source)
.ToList()
Is there a reason you cannot combine the expression into one? I would also add a check that the key exists in the dictionary:
List<LineItem> NALineItems = itemsList.Where(s =>
s.ContainsKey(Constants.ProductSource) && (
String.IsNullOrEmpty(s[Constants.ProductSource]) ||
s[Constants.ProductSource] == source))
.ToList();
I have the following code:
var thing = (from t in things
where t.Type == 1 && t.IsActive
select t).SingleOrDefault();
if (thing == null)
{
// throw exception
}
things is a collection of Entity Framework Self-Tracking Entities
This works nicely, however I want to use a Lambda expression instead and changed the LINQ to this:
var thing = things.Select(t => t.Type == 1 && t.IsActive).SingleOrDefault();
Now Resharper is telling me Expression is always false for (thing == null).
What have I missed?
You want:
var thing = things.Where(t => t.Type == 1 && t.IsActive).SingleOrDefault();
Select performs a projection (converting the type of the IEnumerable from IEnumerable<Thing> to IEnumerable<bool> with values true if t.Type == 1 && t.IsActive == true, otherwise false), then the SingleOrDefault returns either the only bool in this sequence, or the default value of a bool which is false if the sequence is empty. This can never be null since bool is not a reference type.
Where performs a filtering action (pulling out only those objects that meet a given criterion - in this case only selecting those where Type is 1 and IsActive is true), leaving the type of the IEnumerable as IEnumerable<Thing>. Assuming Thing is a class, the SingleOrDefault will return the only item in the sequence or null.
In either case, SingleOrDefault will throw an exception if the sequence contains more than one item (which is far more likely in the Select version!).
I want to filter a list with FindAll
If I write:
.FindAll(
p => p.Field == Value &&
p.otherObjList.Contains(otherObj));
it's ok, but if I write
.FindAll(
p => p.Field == Value &&
p.otherObjList.Contains(
q => q.Field1 == Value1 &&
q.Field2 == Value2));
I get C# syntax error message: Unknown Method FindAll(?) of .. the otherObjList
I cannot define the otherObj exactly, because I know only the values of two fields, Field1 and Field2.
What have I done wrong? What can I do in this case?
The Contains() method for both most collection types as well as the LINQ version expects an argument of the same type as the collection, not a lambda.
It appears you are just trying to check if any item matches some condition. You should use the Any() method.
.FindAll(p => p.Field == Value
&& p.otherObjList.Any(q => q.Field1 == Value1 && q.Field2 == Value2))