1

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?

0

4 Answers 4

3

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))
Sign up to request clarification or add additional context in comments.

Comments

3

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))
....

Comments

1

You can use Contains(). This is the same as IN in sql.

.Where(at => at.AccountId == a.Id 
             && at.LatestVersion 
             && attributeIds.Contains(at.AttributeId))

Comments

1

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))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.