views:

45

answers:

4

I don't know if this is even possible, but how can I access an object property that has be set within an initializer so that I can use it to set another property within the same initializer?

Here's what I'm trying to do:

var usersWithCount =
 users
  .AsEnumerable()
  .Select(
   u =>
   new User()
    {
     UserId = u.UserId,
     UserName = u.UserName,
     Email = u.Email,
     RelatedId = u.RelatedId,
     ReviewCount = u.Reviews.Count(r => !r.Deleted && r.Approved),
     HelpfulYesCount = u.Reviews.Where(r => !r.Deleted && r.Approved).Sum(r => r.HelpfulYes),
     HelpfulNoCount = u.Reviews.Where(r => !r.Deleted && r.Approved).Sum(r => r.HelpfulNo),
     TotalPoints = ReviewCount + HelpfulYesCount - HelpfulNoCount,
     DateCreated = u.DateCreated
    })
  .OrderByDescending(user => user.TotalPoints);

The part that doesn't work is "TotalPoints = ReviewCount + HelpfulYesCount - HelpfulNoCount". I'd rather avoid using "u.Reviews.Count(r => !r.Deleted && r.Approved)" again and I'd don't want to have to loop through the results to add those values together to set TotalPoints.

How can I reference those properties within the initializer that were set above the TotalPoints property? Is there some way I can set them equal to variables and reference them where they are set and where I'm trying to add them? Am I approaching this situation the completely wrong way?

+1  A: 

I presume you could do

...
.Select( u => {
    var rc = u.Reviews.Count(...);
    var hyc = ...;
    ...
    return new User() { /*now reference precomputed vars rc, hyc, ...*/ };})
...

though perhaps there is another/better way.

Brian
This worked perfectly. Thanks!
upheaval
+1  A: 

Why don't you change the TotalPoints property of your User class to return a calculated value? e.g.

public int TotalPoints
{
  get
  {
    return ReviewCount + HelpfulYesCount - HelpfulNoCount
  }
}
tt83
Because the User object is created on the fly
Brett Veenstra
Ok, but surely you must have a class definition for the User object somewhere?
tt83
The User object was created on the fly but I actually added these properties to the object. I tried this option and it did work, but decided to go with Brian's suggestion since the User object is the only object I've added properties to and I might want to do this to a property of an object I haven't added custom properties to. Thanks!
upheaval
A: 

You need two levels for this. Enumerable #1 to calculate your base counts, Enumerable #2 (what you return to consolidate the counts).

Brett Veenstra
+1  A: 

Basically the same as Brian's answer, but in query expression instead of extension methods

from users.AsEnumerable()
let reviewCount = u.Reviews.Count(...)
let helpfulYesCount = u.Reviews.Count(...)
let ...
select new User
{
   ReviewCount = reviewCount,
   ...
}
Sander Rijken