Reputation: 3354
I have the following Linq query which is working fine.
var results = accounts.Select(a => new
{
Id = a.Id,
Scores = _context.AccountAttributeStatistics.Where(at => at.AccountId == a.Id
&& at.LatestVersion && at.AttributeId == 39)
.Select(at => new
{
Id = at.AttributeId,
Percentile = at.Percentile,
Percentage = at.CurrentPercentage,
}).ToList()
});
However I now need to run this for a number if different AttributeIds. I have tried:
Scores = _context.AccountAttributeStatistics.Where(at => at.AccountId == a.Id
&& at.LatestVersion && at.AttributeId == 39 || at.AttributeId == 40
|| at.AttributeId == 41 || at.AttributeId == 42)
Unfortunately this seems to ignore the at.LatestVersion
and returns all scores instead of the latest for these attributes.
What is the best way to get the desires results?
I have thought to use an array and use a foreach but not sure how this would work?
int[] attributeIds = {39, 40, 41, 42, 43};
Scores = _context.AccountAttributeStatistics.Where(at => at.AccountId == a.Id
&& at.LatestVersion && at.AttributeId == attributeIds.ForEach(x => x))
But get the error Only assignment, call, increment, decrement, and new object expressions can be used as a statement
Not sure if that would be the correct way, using linq, to achieve this anyway?
Upvotes: 1
Views: 236
Reputation: 2762
You need to add brackets for that. As you have used the || OR, so it takes all the records having the attributes 40, 41,42 without checking the latest one.
Scores = _context.AccountAttributeStatistics.Where(at => (at.AccountId == a.Id
&& at.LatestVersion) && (at.AttributeId == 39 || at.AttributeId == 40
|| at.AttributeId == 41 || at.AttributeId == 42))
Either use:
int[] attributeIds = {39,40,41,42};
Scores = _context.AccountAttributeStatistics.Where(at => (at.AccountId == a.Id
&& at.LatestVersion) && attributeIds.Contains(at.AttributeId))
Upvotes: 3
Reputation: 460068
In your query brackets were missing so that LatestVersion
is included always. But i would use a collection for the allowed AttributeIds
and use Enumerable.Contains
:
int[] attributeIds = {39, 40, 41, 42, 43};
....
Scores = _context.AccountAttributeStatistics
.Where(at => at.AccountId == a.Id
&& at.LatestVersion
&& attributeIds.Contains(at.AttributeId))
....
Upvotes: 3
Reputation: 796
Just a few additional parentheses would solve your problem:
Scores = _context.AccountAttributeStatistics.Where(at => at.AccountId == a.Id
&& at.LatestVersion && (at.AttributeId == 39 || at.AttributeId == 40
|| at.AttributeId == 41 || at.AttributeId == 42))
Upvotes: 1
Reputation: 263703
You can use Contains(). This is the same as IN
in sql.
.Where(at => at.AccountId == a.Id
&& at.LatestVersion
&& attributeIds.Contains(at.AttributeId))
Upvotes: 1