private bool PopulatePlayerBoxscore( Feeds.FixtureFeed.ApiPlayerBoxscore apiPlayerBoxscore, Feeds.FixtureFeed.ApiLineupPlayerWithStarterStatus apiPlayerLineup, ref PlayerBoxscore dbPlayerBoxscore) { int? playerNumber = null; string position = null; if (apiPlayerBoxscore != null) { playerNumber = apiPlayerBoxscore.Number; position = apiPlayerBoxscore.Position; } else if (apiPlayerLineup != null) { playerNumber = apiPlayerLineup.Number; position = apiPlayerLineup.Position; } bool hasUpdate = false; if (dbPlayerBoxscore.JerseyNumber != playerNumber) { dbPlayerBoxscore.JerseyNumber = playerNumber; hasUpdate = true; } if (dbPlayerBoxscore.Position != position) { dbPlayerBoxscore.Position = position; hasUpdate = true; } // SET ROSTER TYPES IF LINEUP IS AVAILABLE if (apiPlayerLineup != null) { // CAN SET ROSTER TYPE AND HAD TO PLAY AS STARTER if (apiPlayerLineup.IsStarter && (!dbPlayerBoxscore.IsStarter.HasValue || !dbPlayerBoxscore.IsStarter.Value || !dbPlayerBoxscore.Played.HasValue || !dbPlayerBoxscore.Played.Value || !dbPlayerBoxscore.IsBench.HasValue || dbPlayerBoxscore.IsBench.Value)) { dbPlayerBoxscore.IsStarter = true; dbPlayerBoxscore.IsBench = false; dbPlayerBoxscore.Played = true; hasUpdate = true; } // CAN SET ROSTER TYPE, BUT NOT IF PLAYED if (!apiPlayerLineup.IsStarter && (!dbPlayerBoxscore.IsStarter.HasValue || dbPlayerBoxscore.IsStarter.Value || !dbPlayerBoxscore.IsBench.HasValue || !dbPlayerBoxscore.IsBench.Value)) { dbPlayerBoxscore.IsStarter = false; dbPlayerBoxscore.IsBench = true; hasUpdate = true; } } if (apiPlayerBoxscore != null) { if (apiPlayerBoxscore.IsCaptain != dbPlayerBoxscore.IsCaptain || apiPlayerBoxscore.MinutesPlayed != dbPlayerBoxscore.MinutesPlayed || apiPlayerBoxscore.Offsides != dbPlayerBoxscore.Offsides || apiPlayerBoxscore.Rating != dbPlayerBoxscore.Rating || apiPlayerBoxscore.UpdateAt != dbPlayerBoxscore.ApiFootballLastUpdate) { dbPlayerBoxscore.IsCaptain = apiPlayerBoxscore.IsCaptain; dbPlayerBoxscore.MinutesPlayed = apiPlayerBoxscore.MinutesPlayed; dbPlayerBoxscore.Offsides = apiPlayerBoxscore.Offsides; dbPlayerBoxscore.Rating = apiPlayerBoxscore.Rating; dbPlayerBoxscore.ApiFootballLastUpdate = apiPlayerBoxscore.UpdateAt; dbPlayerBoxscore.Played = apiPlayerBoxscore.MinutesPlayed > 0; hasUpdate = true; } if (apiPlayerBoxscore.Cards != null) { if (apiPlayerBoxscore.Cards.Red != dbPlayerBoxscore.RedCards || apiPlayerBoxscore.Cards.Yellow != dbPlayerBoxscore.YellowCards) { dbPlayerBoxscore.RedCards = apiPlayerBoxscore.Cards.Red; dbPlayerBoxscore.YellowCards = apiPlayerBoxscore.Cards.Yellow; hasUpdate = true; } } if (apiPlayerBoxscore.Dribbles != null) { if (apiPlayerBoxscore.Dribbles.Attempts != dbPlayerBoxscore.DribblesAttempted || apiPlayerBoxscore.Dribbles.Past != dbPlayerBoxscore.DribblesPastDef || apiPlayerBoxscore.Dribbles.Success != dbPlayerBoxscore.DribblesSuccessful) { dbPlayerBoxscore.DribblesAttempted = apiPlayerBoxscore.Dribbles.Attempts; dbPlayerBoxscore.DribblesPastDef = apiPlayerBoxscore.Dribbles.Past; dbPlayerBoxscore.DribblesSuccessful = apiPlayerBoxscore.Dribbles.Success; hasUpdate = true; } } if (apiPlayerBoxscore.Duels != null) { if (apiPlayerBoxscore.Duels.Total != dbPlayerBoxscore.DuelsTotal || apiPlayerBoxscore.Duels.Won != dbPlayerBoxscore.DuelsWon) { dbPlayerBoxscore.DuelsTotal = apiPlayerBoxscore.Duels.Total; dbPlayerBoxscore.DuelsWon = apiPlayerBoxscore.Duels.Won; hasUpdate = true; } } if (apiPlayerBoxscore.Fouls != null) { if (apiPlayerBoxscore.Fouls.Committed != dbPlayerBoxscore.FoulsCommitted || apiPlayerBoxscore.Fouls.Drawn != dbPlayerBoxscore.FoulsSuffered) { dbPlayerBoxscore.FoulsCommitted = apiPlayerBoxscore.Fouls.Committed; dbPlayerBoxscore.FoulsSuffered = apiPlayerBoxscore.Fouls.Drawn; hasUpdate = true; } } if (apiPlayerBoxscore.Goals != null) { if (apiPlayerBoxscore.Goals.Assists != dbPlayerBoxscore.Assists || apiPlayerBoxscore.Goals.Conceded != dbPlayerBoxscore.GoalsConceded || apiPlayerBoxscore.Goals.Total != dbPlayerBoxscore.Goals) { dbPlayerBoxscore.Assists = apiPlayerBoxscore.Goals.Assists; dbPlayerBoxscore.GoalsConceded = apiPlayerBoxscore.Goals.Conceded; dbPlayerBoxscore.Goals = apiPlayerBoxscore.Goals.Total; hasUpdate = true; } } if (apiPlayerBoxscore.Passes != null) { if (apiPlayerBoxscore.Passes.Accuracy != dbPlayerBoxscore.PassAccuracy || apiPlayerBoxscore.Passes.Key != dbPlayerBoxscore.KeyPasses || apiPlayerBoxscore.Passes.Total != dbPlayerBoxscore.PassAttempts) { dbPlayerBoxscore.PassAccuracy = apiPlayerBoxscore.Passes.Accuracy; dbPlayerBoxscore.KeyPasses = apiPlayerBoxscore.Passes.Key; dbPlayerBoxscore.PassAttempts = apiPlayerBoxscore.Passes.Total; hasUpdate = true; } } if (apiPlayerBoxscore.Penalty != null) { if (apiPlayerBoxscore.Penalty.Commited != dbPlayerBoxscore.PenaltiesCommitted || apiPlayerBoxscore.Penalty.Missed != dbPlayerBoxscore.PenaltiesMissed || apiPlayerBoxscore.Penalty.Saved != dbPlayerBoxscore.PenaltiesSaved || apiPlayerBoxscore.Penalty.Success != dbPlayerBoxscore.PenaltiesScored || apiPlayerBoxscore.Penalty.Won != dbPlayerBoxscore.PenaltiesWon) { dbPlayerBoxscore.PenaltiesCommitted = apiPlayerBoxscore.Penalty.Commited; dbPlayerBoxscore.PenaltiesMissed = apiPlayerBoxscore.Penalty.Missed; dbPlayerBoxscore.PenaltiesSaved = apiPlayerBoxscore.Penalty.Saved; dbPlayerBoxscore.PenaltiesScored = apiPlayerBoxscore.Penalty.Success; dbPlayerBoxscore.PenaltiesWon = apiPlayerBoxscore.Penalty.Won; hasUpdate = true; } } if (apiPlayerBoxscore.Shots != null) { if (apiPlayerBoxscore.Shots.On != dbPlayerBoxscore.ShotsOnGoal || apiPlayerBoxscore.Shots.Total != dbPlayerBoxscore.ShotsTaken) { dbPlayerBoxscore.ShotsOnGoal = apiPlayerBoxscore.Shots.On; dbPlayerBoxscore.ShotsTaken = apiPlayerBoxscore.Shots.Total; hasUpdate = true; } } if (apiPlayerBoxscore.Tackles != null) { if (apiPlayerBoxscore.Tackles.Blocks != dbPlayerBoxscore.Blocks || apiPlayerBoxscore.Tackles.Interceptions != dbPlayerBoxscore.Interceptions || apiPlayerBoxscore.Tackles.Total != dbPlayerBoxscore.Tackles) { dbPlayerBoxscore.Blocks = apiPlayerBoxscore.Tackles.Blocks; dbPlayerBoxscore.Interceptions = apiPlayerBoxscore.Tackles.Interceptions; dbPlayerBoxscore.Tackles = apiPlayerBoxscore.Tackles.Total; hasUpdate = true; } } } return(hasUpdate); }
public void Run(SoccerDataContext dbContext) { var dbFixture = dbContext.Fixtures.Single(x => x.ApiFootballId == this.ApiFootballFixtureId); var isFixtureFinal = string.Equals("Match Finished", dbFixture.Status, StringComparison.CurrentCultureIgnoreCase); if (!dbFixture.HomeTeamSeasonId.HasValue || !dbFixture.AwayTeamSeasonId.HasValue || !isFixtureFinal) { return; } var url = Feeds.FixtureFeed.GetFeedUrlByFixtureId(this.ApiFootballFixtureId); var rawJson = JsonUtility.GetRawJsonFromUrl(url); var feed = Feeds.FixtureFeed.FromJson(rawJson); Feeds.FixtureFeed.ApiFixture feedFixture = feed.Result.Fixtures.SingleOrDefault(); if (feedFixture == null) { return; } int dbFixtureId = dbFixture.FixtureId; int dbHomeTeamSeasonId = dbFixture.HomeTeamSeasonId.Value; int dbAwayTeamSeasonId = dbFixture.AwayTeamSeasonId.Value; int apiAwayTeamId = feedFixture.AwayTeam.TeamId; int apiHomeTeamId = feedFixture.HomeTeam.TeamId; int?homeCoachId = null; int?awayCoachId = null; var apiPlayerBases = GetApiPlayerBases(feedFixture); var dbPlayerSeasonDict = GetDbPlayerSeasonDict(dbContext, apiPlayerBases, dbFixture.CompetitionSeasonId); bool hasUpdate = false; Feeds.FixtureFeed.ApiLineup homeLineup = null; Feeds.FixtureFeed.ApiLineup awayLineup = null; #region GET FORMATIONS string homeFormation = null; string awayFormation = null; if (feedFixture.Lineups != null && feedFixture.Lineups.Count == 2) { string homeTeamName = feedFixture.HomeTeam.TeamName; string awayTeamName = feedFixture.AwayTeam.TeamName; // MISMATCH BETWEEN PLAYING TEAM NAMES AND LINEUP DICT KEYS HAS OCCURRED (API fixtureID: 188155) bool hasHomeTeamName = feedFixture.Lineups.Any(x => string.Equals(x.Key, homeTeamName, StringComparison.InvariantCultureIgnoreCase)); bool hasAwayTeamName = feedFixture.Lineups.Any(x => string.Equals(x.Key, awayTeamName, StringComparison.InvariantCultureIgnoreCase)); if (!hasHomeTeamName || !hasAwayTeamName) { if (hasHomeTeamName && !hasAwayTeamName) { awayTeamName = feedFixture.Lineups.Keys.Single(x => !string.Equals(x, homeTeamName, StringComparison.InvariantCultureIgnoreCase)); } else if (!hasHomeTeamName && hasAwayTeamName) { homeTeamName = feedFixture.Lineups.Keys.Single(x => !string.Equals(x, awayTeamName, StringComparison.InvariantCultureIgnoreCase)); } else { throw new KeyNotFoundException("INVALID KEYS FOUND FOR FIXTURE LINEUPS"); } } homeLineup = feedFixture.Lineups.Single(x => string.Equals(x.Key, homeTeamName, StringComparison.InvariantCultureIgnoreCase)).Value; awayLineup = feedFixture.Lineups.Single(x => string.Equals(x.Key, awayTeamName, StringComparison.InvariantCultureIgnoreCase)).Value; homeFormation = homeLineup.Formation; awayFormation = awayLineup.Formation; } #endregion GET FORMATIONS #region ENSURE COACHES EXIST if (this.CheckEntitiesExist) { if (homeLineup != null || awayLineup != null) { var apiCoachIds = new[] { homeLineup.CoachId, awayLineup.CoachId }; var dbCoaches = dbContext.Coaches.Where(x => apiCoachIds.Contains(x.ApiFootballId)).ToDictionary(x => x.ApiFootballId, y => y); if (homeLineup?.CoachId != null) { if (!dbCoaches.TryGetValue(homeLineup.CoachId.Value, out Coach dbHomeCoach)) { dbHomeCoach = new Coach { ApiFootballId = homeLineup.CoachId.Value, CoachName = homeLineup.Coach }; dbContext.Coaches.Add(dbHomeCoach); dbContext.SaveChanges(); dbCoaches.Add(dbHomeCoach.CoachId, dbHomeCoach); // DUE TO BAD DATA, HOME COACH AND AWAY COACH MAY BE THE SAME (API GAME 126635) } homeCoachId = dbHomeCoach.CoachId; } if (awayLineup?.CoachId != null) { if (!dbCoaches.TryGetValue(awayLineup.CoachId.Value, out Coach dbAwayCoach)) { dbAwayCoach = new Coach { ApiFootballId = awayLineup.CoachId.Value, CoachName = awayLineup.Coach }; dbContext.Coaches.Add(dbAwayCoach); dbContext.SaveChanges(); } awayCoachId = dbAwayCoach.CoachId; } } } #endregion ENSURE COACHES EXIST #region ENSURE PLAYERS EXIST if (this.CheckEntitiesExist) { var missingApiPlayerIds = apiPlayerBases?.Select(x => x.PlayerId).Where(x => !dbPlayerSeasonDict.ContainsKey(x)).ToList(); if (missingApiPlayerIds != null && missingApiPlayerIds.Count > 0) { foreach (var missingApiPlayerId in missingApiPlayerIds) { var apiPlayerBase = apiPlayerBases.Single(x => x.PlayerId == missingApiPlayerId); var dbPlayer = dbContext.Players.SingleOrDefault(x => x.ApiFootballId == missingApiPlayerId); if (dbPlayer == null) { dbPlayer = new Player { ApiFootballId = missingApiPlayerId, ApiFootballName = apiPlayerBase.PlayerName, PlayerName = apiPlayerBase.PlayerName }; } var dbPlayerSeason = new PlayerSeason { Player = dbPlayer, CompetitionSeasonId = dbFixture.CompetitionSeasonId }; dbContext.Add(dbPlayerSeason); } dbContext.SaveChanges(); dbPlayerSeasonDict = GetDbPlayerSeasonDict(dbContext, apiPlayerBases, dbFixture.CompetitionSeasonId); } } #endregion ENSURE PLAYERS EXIST #region UPDATE FORAMATION AND COACH IF NECESSARY if (homeCoachId.HasValue && dbFixture.HomeCoachId != homeCoachId) { dbFixture.HomeCoachId = homeCoachId; hasUpdate = true; } if (awayCoachId.HasValue && dbFixture.AwayCoachId != awayCoachId) { dbFixture.AwayCoachId = awayCoachId; hasUpdate = true; } if (!string.IsNullOrEmpty(homeFormation) && dbFixture.HomeFormation != homeFormation) { dbFixture.HomeFormation = homeFormation; hasUpdate = true; } if (!string.IsNullOrEmpty(awayFormation) && dbFixture.AwayFormation != awayFormation) { dbFixture.AwayFormation = awayFormation; hasUpdate = true; } #endregion UPDATE FORAMATION AND COACH IF NECESSARY #region FIXTURE EVENTS // HAVE EACH dbFixtureEvent AVAILABLE. ILookup IS AN IMMUTABLE TYPE, SO A DICTIONARY WITH THE COUNT IS ALSO NEEDED TO TRACK THE NUMBER OF OCCURANCES OF EACH EVENT. // THE ILookup IS JUST TO FIND FIND THE DB REFERENCE FOR EACH EVENT TO MANIPULATE var dbFixtureEventLookup = dbContext.FixtureEvents.Where(x => x.FixtureId == dbFixtureId).ToLookup(x => GetFixtureEventKey(x)); var dbFixtureEventToDeleteCountDict = dbContext.FixtureEvents.Where(x => x.FixtureId == dbFixtureId).ToList().GroupBy(x => GetFixtureEventKey(x)).ToDictionary(x => x.Key, y => y.Count()); var apiFixtureEvents = feedFixture.Events?.Where(x => x.TeamId.HasValue).ToList(); if (apiFixtureEvents != null && apiFixtureEvents.Count > 0) { foreach (var apiFixtureEvent in apiFixtureEvents) { int dbTeamSeasonId = apiFixtureEvent.TeamId == apiAwayTeamId ? dbAwayTeamSeasonId : dbHomeTeamSeasonId; int?dbPlayerSeasonId = null; if (dbPlayerSeasonDict != null && apiFixtureEvent.PlayerId.HasValue && dbPlayerSeasonDict.TryGetValue(apiFixtureEvent.PlayerId.Value, out int intPlayerSeasonId)) { dbPlayerSeasonId = intPlayerSeasonId; } int?dbSecondaryPlayerSeasonId = null; if (dbPlayerSeasonDict != null && apiFixtureEvent.SecondaryPlayerId.HasValue && dbPlayerSeasonDict.TryGetValue(apiFixtureEvent.SecondaryPlayerId.Value, out intPlayerSeasonId)) { dbSecondaryPlayerSeasonId = intPlayerSeasonId; } // IT IS POSSIBLE TO HAVE MULTIPLE IDENTICAL EVENTS IN THE SAME MINUTE // API FIXTURE ID 185030 - 2 GOALS BY SAME PLAYER IN SAME MINUTE // USE LOOKUP TO DETERMINE CORRECT AMOUNT OF EXISTENCE var eventKey = GetFixtureEventKey(apiFixtureEvent.Elapsed, apiFixtureEvent.ElapsedPlus, dbPlayerSeasonId, dbTeamSeasonId, apiFixtureEvent.EventType, apiFixtureEvent.EventDetail); var dbCount = dbFixtureEventToDeleteCountDict.TryGetValue(eventKey, out int tempInt) ? tempInt : 0; FixtureEvent dbFixtureEvent; if (dbCount == 0) { dbFixtureEvent = new FixtureEvent { EventComment = apiFixtureEvent.EventComments, EventDetail = apiFixtureEvent.EventDetail, EventType = apiFixtureEvent.EventType, FixtureId = dbFixtureId, EventTime = apiFixtureEvent.Elapsed, EventTimePlus = apiFixtureEvent.ElapsedPlus, PlayerSeasonId = dbPlayerSeasonId, SecondaryPlayerSeasonId = dbSecondaryPlayerSeasonId, TeamSeasonId = dbTeamSeasonId }; dbContext.FixtureEvents.Add(dbFixtureEvent); hasUpdate = true; } else { dbFixtureEvent = dbFixtureEventLookup[eventKey].Skip(dbCount - 1).First(); // TAKE LAST ENTRY IN LOOKUP. AS THE COUNT IN THE dbFixtureEventCount DICTIONARY IS DECREMENTED, THE SELECTED EVENT WILL MOVE DOWN THE LIST if (dbCount == 1) { dbFixtureEventToDeleteCountDict.Remove(eventKey); } else { dbFixtureEventToDeleteCountDict[eventKey] = dbCount - 1; } if ((!string.IsNullOrEmpty(apiFixtureEvent.EventComments) && dbFixtureEvent.EventComment != apiFixtureEvent.EventComments) || (!string.IsNullOrEmpty(apiFixtureEvent.EventDetail) && dbFixtureEvent.EventDetail != apiFixtureEvent.EventDetail) || (dbSecondaryPlayerSeasonId.HasValue && (!dbFixtureEvent.SecondaryPlayerSeasonId.HasValue || dbFixtureEvent.SecondaryPlayerSeasonId != dbSecondaryPlayerSeasonId)) || (!dbSecondaryPlayerSeasonId.HasValue && dbFixtureEvent.SecondaryPlayerSeasonId.HasValue)) { dbFixtureEvent.EventComment = apiFixtureEvent.EventComments; dbFixtureEvent.EventDetail = apiFixtureEvent.EventDetail; dbFixtureEvent.SecondaryPlayerSeasonId = dbSecondaryPlayerSeasonId; hasUpdate = true; } } } if (dbFixtureEventToDeleteCountDict.Count > 0) { foreach (var dbFixtureEventCountEntry in dbFixtureEventToDeleteCountDict) { var dbFixtureEventLookupEntry = dbFixtureEventLookup[dbFixtureEventCountEntry.Key]; int dbFixtureEventCount = dbFixtureEventLookupEntry.Count(); if (dbFixtureEventCount >= 1) { for (int i = dbFixtureEventCount; i >= 1; i--) { var dbFixtureEvent = dbFixtureEventLookupEntry.Skip(i - 1).First(); dbContext.FixtureEvents.Remove(dbFixtureEvent); } } } hasUpdate = true; } } #endregion FIXTURE EVENTS #region TEAM BOXSCORE var apiTeamStatsDict = feedFixture.TeamStatistics; if (apiTeamStatsDict == null) { if (!dbFixture.HasTeamBoxscores.HasValue || dbFixture.HasTeamBoxscores.Value) { hasUpdate = true; } dbFixture.HasTeamBoxscores = false; } else { var dbTeamBoxscores = dbContext.TeamBoxscores.Where(x => x.FixtureId == dbFixtureId); var dbHomeBoxscore = dbTeamBoxscores?.SingleOrDefault(x => x.TeamSeasonId == dbHomeTeamSeasonId); var dbAwayBoxscore = dbTeamBoxscores?.SingleOrDefault(x => x.TeamSeasonId == dbAwayTeamSeasonId); if (dbHomeBoxscore == null) { dbHomeBoxscore = new TeamBoxscore { FixtureId = dbFixtureId, TeamSeasonId = dbHomeTeamSeasonId, OppTeamSeasonId = dbAwayTeamSeasonId, IsHome = true }; dbContext.TeamBoxscores.Add(dbHomeBoxscore); hasUpdate = true; } if (dbAwayBoxscore == null) { dbAwayBoxscore = new TeamBoxscore { FixtureId = dbFixtureId, TeamSeasonId = dbAwayTeamSeasonId, OppTeamSeasonId = dbHomeTeamSeasonId, IsHome = false, }; dbContext.TeamBoxscores.Add(dbAwayBoxscore); hasUpdate = true; } if (PopulateTeamBoxscore(apiTeamStatsDict, x => x.Home, ref dbHomeBoxscore)) { hasUpdate = true; dbFixture.HasTeamBoxscores = true; } if (PopulateTeamBoxscore(apiTeamStatsDict, x => x.Away, ref dbAwayBoxscore)) { hasUpdate = true; dbFixture.HasTeamBoxscores = true; } if (!dbFixture.HasTeamBoxscores.HasValue) { dbFixture.HasTeamBoxscores = false; } } #endregion TEAM BOXSCORE #region PLAYER BOXSCORE if (apiPlayerBases != null && apiPlayerBases.Count > 0) { var dbPlayerBoxscores = dbContext.PlayerBoxscores .Include(x => x.PlayerSeason) .ThenInclude(y => y.Player) .Where(x => x.FixtureId == dbFixtureId && x.PlayerSeason != null && x.PlayerSeason.Player != null) .ToDictionary(x => x.PlayerSeason.Player.ApiFootballId, y => y); bool hasApiPlayerBoxscores = feedFixture?.PlayerBoxscores != null; bool hasApiLineups = feedFixture?.AllLineupPlayers != null; foreach (var apiPlayerBase in apiPlayerBases) { var dbPlayerSeasonId = dbPlayerSeasonDict[apiPlayerBase.PlayerId]; if (!dbPlayerBoxscores.TryGetValue(apiPlayerBase.PlayerId, out PlayerBoxscore dbPlayerBoxscore)) { dbPlayerBoxscore = new PlayerBoxscore { PlayerSeasonId = dbPlayerSeasonId, IsStarter = apiPlayerBase.IsStarter, FixtureId = dbFixtureId, TeamSeasonId = apiPlayerBase.TeamId == feedFixture.HomeTeam.TeamId ? dbHomeTeamSeasonId : dbAwayTeamSeasonId }; dbContext.PlayerBoxscores.Add(dbPlayerBoxscore); hasUpdate = true; } if (hasApiPlayerBoxscores || hasApiLineups) { Feeds.FixtureFeed.ApiPlayerBoxscore apiPlayerBoxscore = null; if (apiPlayerBase.BoxscorePlayerId.HasValue && apiPlayerBase.JerseyNumber.HasValue) { apiPlayerBoxscore = feedFixture.PlayerBoxscores.Where(x => x.PlayerId.HasValue).FirstOrDefault(x => x.Number == apiPlayerBase.JerseyNumber && x.TeamId == apiPlayerBase.TeamId); } Feeds.FixtureFeed.ApiLineupPlayerWithStarterStatus apiPlayerLineup = null; if (apiPlayerBase.LineupPlayerId.HasValue && apiPlayerBase.JerseyNumber.HasValue) { apiPlayerLineup = feedFixture.AllLineupPlayers.Where(x => x.PlayerId.HasValue).FirstOrDefault(x => x.Number == apiPlayerBase.JerseyNumber && x.TeamId == apiPlayerBase.TeamId); } if (apiPlayerBoxscore != null || apiPlayerLineup != null) { if (PopulatePlayerBoxscore(apiPlayerBoxscore, apiPlayerLineup, ref dbPlayerBoxscore)) { hasUpdate = true; } } } } } #endregion PLAYER BOXSCORE if (hasUpdate) { dbContext.SaveChanges(); } }