4

I feel like a one legged man in an ass-kicking contest... I need to add a property to my LINQ dataset which provides a summary based on properties of a sub-collection and then flatten my data. (I'm creating an .rdlc dataset.) I finally figured out how to flatten my data, but I cannot figure out how to derive a value based on which group of reviewers provided their assessment.

I have some assessments and I need to summarize one outcome based on the Reviewer Group the Reviewer belongs to:

  1. If any of the assessments in the review group are "Big Problem", return "Big Problem".

  2. If All assessments say "No Problem", then return "No Problem".

  3. If no assessments are "Big Problem" and at least one is blank, return null.

    Below is a sample set I created to hopefully demonstrate what I'm talking about:

    public List<SummaryReport> CreateReport()
    {
         return Get()
             .SelectMany(rev => rev.Assessments, (rev, ass) => new { rev, ass })
             .Select(x => new SummaryReport
             {
                 ReviewID = x.rev.ReviewID,
                 ReviewerID = x.ass.Reviewer.ReviewerID,
                 Assessment = x.ass.Assessment,
                 ReviewGroupID = x.ass.Reviewer.ReviewGroup.ReviewGroupID,
                 GroupAssessment = "Need to derive this value!!??!?"
              })
             .ToList();
     }
    
    public List<Review> Get()
    {
        ReviewGroup GrpOne = new ReviewGroup(){ ReviewGroupID=1};
        ReviewGroup GrpTwo = new ReviewGroup(){ ReviewGroupID=2};
        ReviewGroup GrpThree = new ReviewGroup(){ ReviewGroupID=3};
    
        ReviewerInfo userOne = new ReviewerInfo() { ReviewerID=1, ReviewGroup = GrpOne};
        ReviewerInfo userTwo = new ReviewerInfo() { ReviewerID=2, ReviewGroup = GrpTwo};
        ReviewerInfo userThree = new ReviewerInfo() { ReviewerID=3, ReviewGroup = GrpTwo};
        ReviewerInfo userFour = new ReviewerInfo() { ReviewerID=4, ReviewGroup = GrpThree};
    
        Assessment asOne = new Assessment() { AssessmentID=1, Reviewer=userOne, Assessment="Big Problem"};
        Assessment asTwo = new Assessment() { AssessmentID=2, Reviewer=userTwo, Assessment="No Problem"};
        Assessment asThree = new Assessment() { AssessmentID=3, Reviewer=userThree, Assessment="No Problem"};
        Assessment asFour = new Assessment() { AssessmentID=4, Reviewer=userFour, Assessment=""};
    
        Assessment asFive = new Assessment() { AssessmentID=5, Reviewer=userOne, Assessment="No Problem"};
        Assessment asSix = new Assessment() { AssessmentID=6, Reviewer=userTwo, Assessment="No Problem"};
        Assessment asSeven = new Assessment() { AssessmentID=7, Reviewer=userThree, Assessment="No Problem"};
        Assessment asEight = new Assessment() { AssessmentID=8, Reviewer=userFour, Assessment="No Problem"};
    
        Assessment asNine = new Assessment() { AssessmentID=9, Reviewer=userOne, Assessment="No Problem"};
        Assessment asTen = new Assessment() { AssessmentID=10, Reviewer=userTwo, Assessment=""};
        Assessment asEleven = new Assessment() { AssessmentID=11, Reviewer=userThree, Assessment="No Problem"};
        Assessment asTwelve = new Assessment() { AssessmentID=12, Reviewer=userFour, Assessment="No Problem"};
    
        List<Assessment> firstList = new List<Assessment>() { asOne, asTwo, asThree, asFour };
        List<Assessment> secondList = new List<Assessment>() {asFive, asSix, asSeven, asEight};
        List<Assessment> thirdList = new List<Assessment>() { asNine, asTen, asEleven, asTwelve };
    
        Review revOne = new Review() { ReviewID=1, Assessments=firstList };
        Review revTwo = new Review() { ReviewID=2, Assessments = secondList };
        Review revThree = new Review() { ReviewID = 3, Assessments = thirdList };
    
        List<Review> reviews = new List<Review>() { revOne, revTwo, revThree };
    
        return reviews;
    }
    
    public class SummaryReport
    {
        public int ReviewID { get; set; }
        public int ReviewerID { get; set; }
        public string Assessment { get; set; }
        public int ReviewGroupID { get; set; }
        public string GroupAssessment { get; set; }
     }
    
    public class Review
    {
         public int ReviewID { get; set; }
         public virtual List<Assessment> Assessments { get; set; }
         public Review() { }
    }
    
    public class Assessment
    {
         public int AssessmentID { get; set; }
         public ReviewerInfo Reviewer { get; set; }
         public string Assessment { get; set; }
    }
    
    public class ReviewerInfo
    {
         public int ReviewerID { get; set; }
         public ReviewGroup ReviewGroup { get; set; }
    }
    
    public class ReviewGroup
    {
         public int ReviewGroupID { get; set; }
    }
    
Community
  • 1
  • 1
Eclipse
  • 293
  • 4
  • 12
  • What is the expected output for your sample data? – Aducci Sep 20 '12 at 18:01
  • 2
    I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Sep 20 '12 at 18:13
  • @Aducci - I was actually trying to create an expected output but I saw an answer before I finished so I stopped. Thanks! – Eclipse Sep 20 '12 at 18:55

2 Answers2

1

You can define a method, and call it during the projection.

Note: Changed Assessment.Assessment property to Assessment.AssessmentDescription so the property name would not be the same as the enclosing type

public List<SummaryReport> CreateReport()
{
 return Get()
     .SelectMany(rev => rev.Assessments, (rev, ass) => new { rev, ass })
     .Select(x => new SummaryReport
     {
         ReviewID = x.rev.ReviewID,
         ReviewerID = x.ass.Reviewer.ReviewerID,
         Assessment = x.ass.Assessment,
         ReviewGroupID = x.ass.Reviewer.ReviewGroup.ReviewGroupID,
         GroupAssessment = DeriveGroupAssessment(x.rev.Assessments)
      })
     .ToList();
 }


private static string DeriveGroupAssessment(IEnumerable<Assessment> assessments)
{
  string assessment = null;

  if (assessments.Any(a => a.AssessmentDescription == "Big Problem"))
  {
    assessment = "Big Problem";
  }
  else if (assessments.All(a => a.AssessmentDescription == "No Problem"))
  {
    assessment = "No Problem";
  }

  // If you want the value to be null if neither of the above conditions are met, this logic is not needed
  ////if (!assessments.Any(a => a.AssessmentDescription == "Big Problem")
  ////    && assessments.Any(a => a.AssessmentDescription == string.Empty))
  ////{
  ////  assessment = null;
  ////}

  return assessment;
}
dugas
  • 12,025
  • 3
  • 45
  • 51
  • Thanks!! I didn't even think to call a method. I figured it had to be a relatively easy solution. – Eclipse Sep 20 '12 at 18:52
1

Try,

 public static List<SummaryReport> CreateReport()
    {
        return Get()
            .SelectMany(rev => rev.Assessments, (rev, ass) => new { rev, ass })
            .Select(x => new SummaryReport
            {
                ReviewID = x.rev.ReviewID,
                ReviewerID = x.ass.Reviewer.ReviewerID,
                Assessment = x.ass.AssessmentStr,
                ReviewGroupID = x.ass.Reviewer.ReviewGroup.ReviewGroupID,
                GroupAssessment = x.rev.Assessments.Any(a => a.AssessmentStr == "Big Problem") ? "Big Problem" : 
                x.rev.Assessments.All(a => a.AssessmentStr == "No Problem")? "No Problem" : null
            })
            .ToList();
    }

Changed name of Assessment property to AssessmentStr because C# not allow property name same as class name.

Jignesh Thakker
  • 3,638
  • 2
  • 28
  • 35
  • Thanks for the response. I'm sure this one would work as well. I just went with dugas' answer because I saw his before this one. – Eclipse Sep 20 '12 at 18:53