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.
.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.
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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With