Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find the opposite of .Any()

Tags:

c#

.net

linq

My brain is failing me on a query I need to set up.

I have a Cat object that has two (relevant) properties:

public virtual ICollection<Ribbon> Ribbons { get; set; }
public virtual ICollection<Trophy> Trophies { get; set; }

Both Ribbon and Trophy has an integer property named "UmbracoActivityId" The ribbons and trophies aren't directly related to each other but they're both related to a cat and an UmbracoActivity. Cats get a ribbon for each "step" they complete in an UmbracoActivity and a trophy for finishing all the steps. They're very competitive cats :)

What I need to do is get a count of cats who have started the UmbracoActivity but haven't completed all the steps (have not received a trophy).

In plain English: find all distinct ribbons where the cat that has the ribbon DOES NOT have a trophy with the same UmbracoActivityId as the ribbon's UmbracoActivityId.

What I've got in code:

var ribbons = db.Ribbons
   .Where(ribbon => db.Cats.Find(ribbon.CatId)
       .Trophies.Any(trophy => trophy.UmbracoActivityId == ribbon.UmbracoActivityId));

I'm getting close but the .Any() statement is true if the ribbon DOES have a trophy with the same UmbracoActivityId. I need the opposite. It's temping to just switch "==" to "!=" but in this case a cat could have many trophies with a different UmbracoActivityId.

I need the reverse the statement somewhere to search for the opposite but I'm not sure where to do that :(

Thanks in advance.

like image 866
allen.mn Avatar asked Mar 13 '13 22:03

allen.mn


Video Answer


2 Answers

.Any(x == y) -> .All(x != y)

If there is any match, the first one succeeds. Else it fails.

If there is any match, the second one fails. Else it succeeds.

like image 190
Patashu Avatar answered Sep 22 '22 06:09

Patashu


Just use negation - i.e. Where(ribbon => !db...Any(...)) (note the added !).

If any trophies share the same UmbracoActivityId, then the cat will not be included.

var ribbons = db.Ribbons
   .Where(ribbon => !db.Cats.Find(ribbon.CatId)
       .Trophies.Any(trophy => trophy.UmbracoActivityId == ribbon.UmbracoActivityId));
like image 43
voithos Avatar answered Sep 23 '22 06:09

voithos