public ActionResult GetDocumentsForCriticalReviewDiscussion(int discussionTeamId) { DiscussionTeam dt = db.DiscussionTeams.Find(discussionTeamId); Assignment CRAssignment = dt.Assignment.PreceedingAssignment; Assignment CRDAssignment = dt.Assignment; Assignment BasicAssignment = CRAssignment.PreceedingAssignment; Team AuthorTeam = dt.AuthorTeam; //Permission checking: // assert that the activeCourseUser is a member of the discussion team of discussionTeamID bool belongsToDiscussionTeam = false; foreach (TeamMember tm in dt.GetAllTeamMembers()) { if (tm.CourseUserID == ActiveCourseUser.ID) { belongsToDiscussionTeam = true; break; } } //If user does not belong to DiscussionTeam and is not an instructor, do not let them get the documents if (belongsToDiscussionTeam || ActiveCourseUser.AbstractRole.CanModify || ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.Observer) { string zipFileName = "Critical Review Discussion Items for " + dt.TeamName + ".zip"; return(GetAllReviewedDocuments(CRAssignment, AuthorTeam, zipFileName, CRDAssignment.DiscussionSettings)); } return(RedirectToAction("Index", "Home")); }
/// <summary> /// This class will set up a list of DiscussionPostViewModels for a discussion based assignment. Note: Virtual calls will not work off of public /// attributes within this view model, unless you append to the queries that gather them a ".Include("VirtualMember")" statement. /// </summary> /// <param name="DiscussionTeam">The discussion team to generate view models for</param> /// <param name="CurrentUser">The current user</param> public DiscussionViewModel(DiscussionTeam DiscussionTeam, CourseUser CurrentUser) { currentUser = CurrentUser; discussionTeam = DiscussionTeam; discussionPostViewModels = new List <DiscussionPostViewModel>(); ReplyViewModels = new List <ReplyViewModel>(); if (discussionTeam.Assignment.Type == AssignmentTypes.CriticalReviewDiscussion) { InitializeViewModelForCriticalReviewDiscussion(); } else { InitializeViewModelForDiscussionAssignment(); } }
public ActionResult CreateDiscussionTeam(int discussionTeamId) { List <UserProfile> recipientList = new List <UserProfile>(); DiscussionTeam discussionTeam = db.DiscussionTeams.Find(discussionTeamId); foreach (TeamMember tm in discussionTeam.GetAllTeamMembers()) { if (tm.CourseUserID != ActiveCourseUser.ID) { recipientList.Add(tm.CourseUser.UserProfile); } } setUpMailViewBags(recipientList); return(View("Create", new Mail())); }
/// <summary> /// Updates discussion teams based off any name changes or team member changes. Creates new teams if needed and purges empty teams. /// </summary> protected void ParseFormValues() { //Wiping all DiscussionTeam.TeamMembers. foreach (DiscussionTeam dt in Assignment.DiscussionTeams) { dt.Team.TeamMembers.Clear(); } db.SaveChanges(); if (Request.Form.AllKeys.Contains("AutoGenFromPastButton")) { //we don't want to continue so force success to be false WasUpdateSuccessful = false; int assignmentId = Assignment.ID; Int32.TryParse(Request.Form["AutoGenFromPastSelect"].ToString(), out assignmentId); Assignment otherAssignment = db.Assignments.Find(assignmentId); List <IAssignmentTeam> otherTeams = null; switch (otherAssignment.Type) { case AssignmentTypes.DiscussionAssignment: case AssignmentTypes.CriticalReviewDiscussion: otherTeams = RemoveWithdrawnMembers(otherAssignment.DiscussionTeams.Cast <IAssignmentTeam>().ToList(), "Discussion"); break; default: otherTeams = RemoveWithdrawnMembers(otherAssignment.AssignmentTeams.Cast <IAssignmentTeam>().ToList(), "Assignment"); break; } SetUpViewBag(otherTeams); } else { string[] studentKeys = Request.Form.AllKeys.Where(k => k.Contains("student_")).ToArray(); List <string> TeamNames = new List <string>();; //This will be a list of the TeamNames from the form. These can be pre-existing teams or new teams. foreach (string studentKey in studentKeys) { TeamNames.Add(Request.Form[studentKey]); } string[] PreExistingTeamKeys = Request.Form.AllKeys.Where(k => k.Contains("team_")).ToArray(); //These are keys for teams that already existed foreach (string preExistingTeamKey in PreExistingTeamKeys) //Determining if each preexisting team should be kept or deleted { string TeamName = Request.Form[preExistingTeamKey]; int TeamID; Int32.TryParse(preExistingTeamKey.Split('_')[1], out TeamID); Team team = Assignment.DiscussionTeams.Where(dt => dt.TeamID == TeamID).Select(dt => dt.Team).FirstOrDefault(); if (TeamNames.Contains(TeamName)) //The TeamName corrisponds to a team that a student is on. { //Save new name if team exists, in case of rename if (team != null) { team.Name = TeamName; db.SaveChanges(); } //If the team has the same ID, then its safe to keep. If it does not, we must delete it, as it //has been deleted by the user and recreated with the same name. Meaning a complete different team. bool TeamHasSameID = Assignment.DiscussionTeams.Where(dt => dt.TeamID == TeamID).Count() > 0; if (TeamHasSameID == false) { //Team has a new ID, but a pre-existing name. Team must have been delete/recreated. So we must //do the same if (team != null) { db.Teams.Remove(team); db.SaveChanges(); } } } else //The TeamName does not corrispond with any Team a student is associated with. So delete it { if (team != null) { DiscussionTeam temp = (from dt in db.DiscussionTeams where dt.TeamID == team.ID select dt).FirstOrDefault(); db.DiscussionTeams.Remove(temp); db.SaveChanges(); db.Teams.Remove(team); db.SaveChanges(); } } } //At this point, all old teams have been purged. So any team from the studentKeys values are either //new teams, or preexisting teams. foreach (string studentKey in studentKeys) { Team team = Assignment.DiscussionTeams.Where(dt => dt.TeamName == Request.Form[studentKey]).Select(dt => dt.Team).FirstOrDefault(); if (team == null) //a new team. Create the team and discussion team before continuing. { team = new Team(); team.Name = Request.Form[studentKey]; db.Teams.Add(team); db.SaveChanges(); DiscussionTeam dt = new DiscussionTeam(); dt.TeamID = team.ID; dt.AssignmentID = Assignment.ID; db.DiscussionTeams.Add(dt); db.SaveChanges(); } int courseUserId = 0; Int32.TryParse(studentKey.Split('_')[1], out courseUserId); // Copy any initial posts made on a different team CopyInitialPosts(team, courseUserId); TeamMember tm = new TeamMember(); tm.TeamID = team.ID; tm.CourseUserID = courseUserId; db.TeamMembers.Add(tm); db.SaveChanges(); } } //get all moderator form keys string[] modKeys = Request.Form.AllKeys.Where(k => k.Contains("moderator_")).ToArray(); List <Team> teams = Assignment.DiscussionTeams.Select(dt => dt.Team).ToList(); foreach (string key in modKeys) { //grab the comma seperated string that has all the teams the moderator is on string[] TeamList = Request.Form[key].Split(','); int courseUserId = 0; if (!Int32.TryParse(key.Split('_')[1], out courseUserId)) //if we fail to get a courseUserId, move on. { continue; } for (int i = 0; i < TeamList.Count(); i++) { //Here, unlike for students, we will only add the moderators to preexisting teams. if (TeamList[i] != "") { Team team = teams.Find(t => t.Name.CompareTo(TeamList[i]) == 0); if (team != null) { TeamMember tm = new TeamMember() { CourseUserID = courseUserId, Team = team }; team.TeamMembers.Add(tm); db.SaveChanges(); //save new members onto team } } } } //Checking for empty teams one last time to be sure List <DiscussionTeam> dtsToRemove = Assignment.DiscussionTeams.Where(dt => dt.Team.TeamMembers.Count == 0).ToList(); for (int i = dtsToRemove.Count - 1; i >= 0; i--) { db.DiscussionTeams.Remove(dtsToRemove[i]); } db.SaveChanges(); }
public ActionResult StudentTeamEvaluation(int assignmentId) { Assignment a = db.Assignments.Find(assignmentId); Team previousTeam; if (a.PreceedingAssignment.Type == AssignmentTypes.DiscussionAssignment) { //Note: This could have non-student types on the team, such as moderators or TAs DiscussionTeam dt = GetDiscussionTeam(a.PreceedingAssignment, ActiveCourseUser); previousTeam = new Team(); previousTeam.TeamMembers = dt.Team.TeamMembers.Where(tm => tm.CourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.Student).ToList(); } else { previousTeam = GetAssignmentTeam(a.PreceedingAssignment, ActiveCourseUser).Team; } AssignmentTeam at = GetAssignmentTeam(a, ActiveCourseUser); if (at != null && a.Type == AssignmentTypes.TeamEvaluation) { ViewBag.AssignmentTeam = at; ViewBag.PreviousTeam = previousTeam; List <TeamEvaluation> teamEvals = (from te in db.TeamEvaluations where te.TeamEvaluationAssignmentID == assignmentId && te.EvaluatorID == ActiveCourseUser.ID orderby te.Recipient.UserProfile.LastName select te).ToList(); //MG: evaluator (currentuser) must have completed at as many evaluations as team members from the previous assignment. //Otherwise, use artificial team evals for view if (teamEvals.Count < previousTeam.TeamMembers.Count) //Creating new team eval { List <TeamEvaluation> artificialTeamEvals = new List <TeamEvaluation>(); foreach (TeamMember tm in previousTeam.TeamMembers.OrderBy(tm2 => tm2.CourseUser.UserProfile.LastName)) { TeamEvaluation te = new TeamEvaluation(); te.Points = 0; te.Recipient = tm.CourseUser; artificialTeamEvals.Add(te); } ViewBag.SubmitButtonValue = "Submit"; ViewBag.TeamEvaluations = artificialTeamEvals; ViewBag.InitialPointsPossible = previousTeam.TeamMembers.Count * 100; } else //using existing team evals { ViewBag.InitialPointsPossible = 0; //Must be 0 as we are reloading old TEs, and requirements for submitting initially are that points possible must be 0 ViewBag.Comment = teamEvals.FirstOrDefault().Comment; ViewBag.SubmitButtonValue = "Resubmit"; ViewBag.TeamEvaluations = teamEvals; } return(View("_StudentTeamEvaluationView")); } else { return(View("Index")); } }
public ActionResult TeacherIndex(int assignmentId, int discussionTeamID, int courseUserId = 0, string highlightValueString = "None", bool anonymous = false) { HighlightValue highlightValue; Enum.TryParse(highlightValueString, out highlightValue); Assignment assignment = db.Assignments.Find(assignmentId); if (assignment.CourseID == ActiveCourseUser.AbstractCourseID && ActiveCourseUser.AbstractRole.CanGrade) { List <DiscussionPost> posts = null; CourseUser student; DiscussionTeam discussionTeam = (from dt in assignment.DiscussionTeams where dt.ID == discussionTeamID select dt).FirstOrDefault(); DiscussionViewModel dvm = new DiscussionViewModel(discussionTeam, ActiveCourseUser); //anonymize if requested if (anonymous == true) { foreach (DiscussionPostViewModel vm in dvm.DiscussionPostViewModels) { vm.poster.Anonymize = true; foreach (ReplyViewModel rvm in vm.Replies) { rvm.poster.Anonymize = true; } } } if (highlightValue == HighlightValue.None || courseUserId <= 0) //If hightlightValue == None, we want no selections - so setting student to null. { student = null; } else { student = db.CourseUsers.Find(courseUserId); } if (assignment.HasDiscussionTeams) { ViewBag.DiscussionHeader = assignment.AssignmentName + " - " + discussionTeam.TeamName; } else { ViewBag.DiscussionHeader = assignment.AssignmentName; } bool canPost = true; //If the user is a TA and TAs can only participate in some discussions, then we must confirm the TA //is in the team before we give them permission to post if (ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.TA && !assignment.DiscussionSettings.TAsCanPostToAllDiscussions && discussionTeam.Team.TeamMembers.Where(tm => tm.CourseUserID == ActiveCourseUser.ID).ToList().Count == 0) { canPost = false; } //for CRD assignment types we need a list of all discussions they can participate in for navigation. //additionally for CRD assignments we want to display all teammates invovled in the discussion if (assignment.HasDiscussionTeams) { ViewBag.DiscussionTeamList = assignment.DiscussionTeams; } ViewBag.LastVisit = GetAndUpdateLastVisit(discussionTeamID); ViewBag.CanPost = canPost; ViewBag.DiscussionPostViewModelList = dvm.DiscussionPostViewModels; ViewBag.HighlightValue = highlightValue; ViewBag.Posts = posts; ViewBag.Student = student; ViewBag.Assignment = assignment; ViewBag.IsFirstPost = false; ViewBag.ActiveCourse = ActiveCourseUser; ViewBag.DiscussionTeamID = discussionTeam.ID; ViewBag.IsAnonymous = anonymous; ViewBag.DiscussionTeam = discussionTeam; return(View("Index")); } return(RedirectToAction("Index", "Home", new { area = "AssignmentDetails", assignmentId = assignmentId })); }
/// <summary> /// This is the discussion view used by non-Instructor/non-TA users. It displays a discussion assignment for discussionTeamId. /// </summary> /// <param name="assignmentId"></param> /// <param name="discussionTeamId"></param> /// <param name="displayNewPosts">If true, any new posts made since the current users last visit will be highlighted.</param> /// <returns></returns> public ActionResult Index(int assignmentId, int discussionTeamId, bool?displayNewPosts = false) { ViewBag.HideMail = OSBLE.Utility.DBHelper.GetAbstractCourseHideMailValue(ActiveCourseUser.AbstractCourseID); Assignment assignment = null; DiscussionTeam discussionTeam = null; //checking if ids are good if (discussionTeamId > 0 && assignmentId > 0) { assignment = db.Assignments.Find(assignmentId); discussionTeam = (from dt in assignment.DiscussionTeams where dt.ID == discussionTeamId select dt).FirstOrDefault(); } //Make sure ActiveCourseUser is a valid discussion member //Valid discussion members are in the discussion team, or in the class of a classwide discussion assignment bool allowedInDiscussion = false; if (assignment != null && assignment.HasDiscussionTeams == false)//Classwide discussion { //make sure user is in course if (ActiveCourseUser.AbstractCourseID == assignment.CourseID) { allowedInDiscussion = true; } } else if (assignment != null && discussionTeam != null)//Assignment has discussion teams { //make sure user is part of team. foreach (TeamMember tm in discussionTeam.GetAllTeamMembers()) { if (tm.CourseUserID == ActiveCourseUser.ID) { allowedInDiscussion = true; break; } } } //if ActiveCourseUser belongs to the discussionTeam, continue. Otherwise kick them out. if (allowedInDiscussion || ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.Observer) { DiscussionViewModel dvm = new DiscussionViewModel(discussionTeam, ActiveCourseUser); //Checking if its users first post ViewBag.IsFirstPost = (from dpvm in dvm.DiscussionPostViewModels where dpvm.poster.CourseUser.ID == ActiveCourseUser.ID select dpvm).Count() == 0; //assigning a header value. if (assignment.HasDiscussionTeams) { ViewBag.DiscussionHeader = assignment.AssignmentName + "- " + discussionTeam.TeamName; } else { ViewBag.DiscussionHeader = assignment.AssignmentName; } //for CRD assignment types we need a list of all discussions they can participate in for navigation. if (assignment.Type == AssignmentTypes.CriticalReviewDiscussion) { List <DiscussionTeam> DiscussionTeamList = new List <DiscussionTeam>(); //Generating a list of discussion assignments that the current user belongs to foreach (DiscussionTeam dt in assignment.DiscussionTeams) { foreach (TeamMember tm in dt.GetAllTeamMembers()) { if (tm.CourseUserID == ActiveCourseUser.ID) { DiscussionTeamList.Add(dt); break; } } } ViewBag.DiscussionTeamList = DiscussionTeamList.OrderBy(dt => dt.TeamName).ToList(); } if (displayNewPosts.HasValue && displayNewPosts.Value) { ViewBag.HighlightValue = HighlightValue.NewPosts; } //Allow Moderators to post w/o word count restriction if (ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.Moderator) { ViewBag.IsFirstPost = false; } ViewBag.LastVisit = GetAndUpdateLastVisit(discussionTeamId); if (ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.Observer) { ViewBag.CanPost = false; } else { ViewBag.CanPost = assignment.DueDate > DateTime.UtcNow; } ViewBag.DiscussionPostViewModelList = dvm.DiscussionPostViewModels.OrderBy(dpvm => dpvm.Posted).ToList(); ViewBag.ActiveCourse = ActiveCourseUser; ViewBag.Assignment = assignment; ViewBag.DiscussionTeamID = discussionTeam.ID; ViewBag.DiscussionTeam = discussionTeam; return(View()); } else //User is not part of discussion, kick them to assignment details. { return(RedirectToAction("Index", "Home", new { area = "AssignmentDetails", assignmentId = assignmentId })); } }
private void UpdateCriticalReviewDiscussions() { //Getting a list of CRDs that used this Critical Review List <Assignment> relatedCriticalReviewDiscussions = (from a in db.Assignments where a.AssignmentTypeID == (int)AssignmentTypes.CriticalReviewDiscussion && a.PrecededingAssignmentID == Assignment.ID select a).ToList(); foreach (Assignment CRDassignment in relatedCriticalReviewDiscussions) { //The discussion teams from the CRD are potentially orphans, at the end of this iteration, any teams that are still orphans will be deleted. List <DiscussionTeam> orphanTeams = CRDassignment.DiscussionTeams.ToList(); List <int> authorTeamIds = Assignment.ReviewTeams.Select(rt => rt.AuthorTeamID).Distinct().ToList(); //There will be at most 1 DiscussionTeam for each AuthorTeam. So, looking for existing //discussion teams to edit. int i = 1; foreach (int authorTeamId in authorTeamIds) { DiscussionTeam existingDiscussionTeam = orphanTeams.Where(dt => dt.AuthorTeamID == authorTeamId).FirstOrDefault(); if (existingDiscussionTeam == null) //There was no team. This could occur if Team X had no reviewers before the edit, and now has reviewers. { //Create new DiscussionTeam and Team for existingDiscussionTeam existingDiscussionTeam = new DiscussionTeam(); existingDiscussionTeam.AuthorTeamID = authorTeamId; existingDiscussionTeam.AssignmentID = CRDassignment.ID; Team newTeam = new Team(); //Keep trying to generate unique name do { newTeam.Name = "Discussion Team 0" + i; i++; } while (CRDassignment.DiscussionTeams.Where(dt => dt.TeamName == newTeam.Name).Count() > 0); existingDiscussionTeam.Team = newTeam; db.DiscussionTeams.Add(existingDiscussionTeam); db.SaveChanges(); } else //Team still exists, remove from orphan list. { orphanTeams.Remove(existingDiscussionTeam); } //ExistingDiscussionTeam.Team.TeamMembers need to be wiped and refreshed with those who exist in the review team existingDiscussionTeam.Team.TeamMembers.Clear(); //Add each reviewer to existingDiscussionTeam.Team, only once. //MG: Note, the reason the team Ids are collected and then a db query for the teams is because assignment's aren't properly doing a virtual call //to collect their review teams, as all review teams are null. List <int> reviewTeamIds = Assignment.ReviewTeams.Where(rt => rt.AuthorTeamID == authorTeamId).Select(rt => rt.ReviewTeamID).ToList(); List <Team> reviewTeams = (from team in db.Teams where reviewTeamIds.Contains(team.ID) select team).ToList(); foreach (Team reviewTeam in reviewTeams) { foreach (TeamMember reviewer in reviewTeam.TeamMembers) { //Checking if reviewer is already on team bool alreadyOnTeam = (from tm in existingDiscussionTeam.Team.TeamMembers where tm.CourseUserID == reviewer.CourseUserID select tm).Count() > 0; //If not on team, Create a new team member for them, and add to existingDiscussionTeam.Team if (alreadyOnTeam == false) { TeamMember newMember = new TeamMember(); newMember.CourseUserID = reviewer.CourseUserID; newMember.TeamID = existingDiscussionTeam.TeamID; existingDiscussionTeam.Team.TeamMembers.Add(newMember); } } } } //Remove any remainig orphanTeams foreach (DiscussionTeam orphan in orphanTeams) { db.DiscussionTeams.Remove(orphan); } db.SaveChanges(); } }
public override ActionResult Index() { base.Index(); //Only creating the discussion teams for the assignment if DiscussionTeams do not exist. if (Assignment.DiscussionTeams == null || Assignment.DiscussionTeams.Count == 0) { List <DiscussionTeam> discussionTeams = new List <DiscussionTeam>(); Dictionary <int, Team> TeamDict = new Dictionary <int, Team>(); List <Team> authorTeams = (from rt in Assignment.PreceedingAssignment.ReviewTeams select rt.AuthorTeam).Distinct().ToList(); int i = 1; //Foreach author team, creating a new DiscussionTeam who consists of all the people //who reviewed that author team as well as that author team. foreach (Team authorTeam in authorTeams) { DiscussionTeam dt = new DiscussionTeam(); Team team = new Team(); List <Team> reviewTeams = (from rt in Assignment.PreceedingAssignment.ReviewTeams where rt.AuthorTeamID == authorTeam.ID select rt.ReviewingTeam).ToList(); //Adding all the reviewing team members to the Team foreach (Team reviewerTeam in reviewTeams) { //Generating a list of all team members in the review team and the author team List <TeamMember> newTeamMembers = reviewerTeam.TeamMembers.ToList(); //Going through all the team members, creating new team members out of them and associating them with our newly created team. foreach (TeamMember tm in newTeamMembers) { TeamMember newTm = new TeamMember(); newTm.CourseUserID = tm.CourseUserID; newTm.Team = team; newTm.CourseUser = tm.CourseUser; //Checking to see if member already exists in team. Only adding them if they are not on team. bool alreadyInTeam = false; foreach (TeamMember currentMember in team.TeamMembers) { if (currentMember.CourseUserID == newTm.CourseUserID) { alreadyInTeam = true; } } if (alreadyInTeam == false) { team.TeamMembers.Add(newTm); } } } dt.AuthorTeam = authorTeam; dt.AuthorTeamID = authorTeam.ID; //Naming the team and associating the team with a discussion team. Note: Nameing is: Discussion Team 01...02..10..11... if (i < 10) { team.Name = "Discussion Team 0" + i.ToString(); } else { team.Name = "Discussion Team " + i.ToString(); } i++; dt.Team = team; dt.AssignmentID = Assignment.ID; discussionTeams.Add(dt); } //Associating the list of discussion teams with the Critical Review Discussion assignment Assignment.DiscussionTeams = discussionTeams; db.SaveChanges(); } ViewBag.criticalReviewDiscussionTeams = Assignment.DiscussionTeams; SetUpModeratorViewBag(); return(View(Assignment)); }
//For Critical Review Discussions, teams are never added. They are all built prior to the view. //Because of this assumption, we only have to watch for Moderators/TAs being added to an existing team //and a team's name changing. protected void ParseFormValues() { //collecting list of TeamMembers from the assignment that are Moderators or TAs List <TeamMember> ModeratorAndTATeamMembers = Assignment.DiscussionTeams.SelectMany(dt => dt.Team.TeamMembers) .Where(tm => (tm.CourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.TA) || (tm.CourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.Moderator)).ToList(); foreach (TeamMember tm in ModeratorAndTATeamMembers) { db.TeamMembers.Remove(tm); } //Setting team names string[] teamKeys = Request.Form.AllKeys.Where(k => k.Contains("discussionTeamName_")).ToArray(); foreach (string key in teamKeys) { string TeamName = Request.Form[key]; int discTeamID = 0; if (!Int32.TryParse(key.Split('_')[1], out discTeamID)) { //Should never get here, but skip in case continue; } DiscussionTeam currentDt = Assignment.DiscussionTeams.Where(dt => dt.ID == discTeamID).FirstOrDefault(); if (currentDt == null) { //Should never get here, but skip in case continue; } //Assigning name currentDt.Team.Name = TeamName; } //grabbing all hidden moderator keys string[] moderatorKeys = Request.Form.AllKeys.Where(k => k.Contains("moderator_")).ToArray(); foreach (string key in moderatorKeys) { int courseUserId = 0; if (!Int32.TryParse(key.Split('_')[1], out courseUserId)) { //if we fail to get a courseUserId, move on. continue; } string[] discussionTeamIDList = Request.Form[key].Split(','); foreach (string discussionTeamId in discussionTeamIDList) { int discTeamID = 0; if (!Int32.TryParse(discussionTeamId, out discTeamID)) { //Should never get here, but skip in case continue; } Team TeamForNewTM = Assignment.DiscussionTeams.Where(dt => dt.ID == discTeamID).Select(dt => dt.Team).FirstOrDefault(); //Can safely add the new TM to the team without fear of duplication because TA/moderators are removed from all teams initially TeamMember newTM = new TeamMember() { Team = TeamForNewTM, CourseUserID = courseUserId }; TeamForNewTM.TeamMembers.Add(newTM); } } db.SaveChanges(); }