public void Run(SoccerDataContext dbContext) { var url = Feeds.CountriesFeed.GetFeedUrl(); var rawJson = JsonUtility.GetRawJsonFromUrl(url); var feed = Feeds.CountriesFeed.FromJson(rawJson); var orderedCountries = feed.Result.Countries .OrderBy(x => string.Equals(x.CountryName, "World", StringComparison.InvariantCultureIgnoreCase) ? 0 : 1) .ThenBy(x => x.Code) .ToList(); var existingCountries = dbContext.Countries.ToDictionary(x => x.ApiFootballCountryName); foreach (var country in orderedCountries) { if (!existingCountries.ContainsKey(country.CountryName)) { var dbCountry = new Country { CountryName = country.CountryName, CountryAbbr = country.Code, FlagUrl = country.Flag?.ToString(), ApiFootballCountryName = country.CountryName }; existingCountries.Add(country.CountryName, dbCountry); dbContext.Countries.Add(dbCountry); dbContext.SaveChanges(); } } if (dbContext.Countries.Count(x => string.Equals(x.ApiFootballCountryName.ToUpper(), "SCOTLAND")) == 0) { dbContext.Add(new Country { ApiFootballCountryName = "Scotland", CountryAbbr = "GB", CountryName = "Scotland" }); dbContext.SaveChanges(); } if (dbContext.Countries.Count(x => string.Equals(x.ApiFootballCountryName.ToUpper(), "NORTHERN-IRELAND")) == 0) { dbContext.Add(new Country { ApiFootballCountryName = "Northern-Ireland", CountryAbbr = "GB", CountryName = "Northern Ireland" }); dbContext.SaveChanges(); } if (dbContext.Countries.Count(x => string.Equals(x.ApiFootballCountryName.ToUpper(), "SWAZILAND")) == 0) { dbContext.Add(new Country { ApiFootballCountryName = "Swaziland", CountryAbbr = "SW", CountryName = "Eswatini" }); dbContext.SaveChanges(); } }
private Dictionary <int, int> GetDbPlayerSeasonDict(SoccerDataContext dbContext, List <ApiPlayerBase> apiPlayerBases, int dbCompetitionSeasonId) { if (apiPlayerBases == null || apiPlayerBases.Count == 0) { return(null); } var apiPlayerIds = apiPlayerBases.Select(x => x.PlayerId).ToList(); return(dbContext.PlayerSeasons .Include(x => x.Player) .Where(x => x.CompetitionSeasonId == dbCompetitionSeasonId && apiPlayerIds.Contains(x.Player.ApiFootballId)) .ToDictionary(x => x.Player.ApiFootballId, y => y.PlayerSeasonId)); }
public void Run(SoccerDataContext dbContext) { var dbCompetitionSeason = dbContext.CompetitionSeasons .Include(x => x.CompetitionSeasonRounds) .Include(x => x.Competition) .SingleOrDefault(x => x.CompetitionSeasonId == this.CompetitionSeasonId); if (dbCompetitionSeason == null) { return; } Console.WriteLine($"CSR-{dbCompetitionSeason.CompetitionSeasonId}-{dbCompetitionSeason.Season}-{dbCompetitionSeason.Competition.CompetitionName}"); var url = Feeds.CompetitionSeasonRoundsFeed.GetFeedUrlByLeagueId(dbCompetitionSeason.ApiFootballId); var rawJson = JsonUtility.GetRawJsonFromUrl(url); var feed = Feeds.CompetitionSeasonRoundsFeed.FromJson(rawJson); var dbRounds = dbCompetitionSeason.CompetitionSeasonRounds.ToList(); var feedRounds = feed.Result.Rounds.Select(x => x.Replace('_', ' ')).ToList(); bool hasUpdates = false; foreach (var feedRound in feedRounds) { var dbRound = dbRounds.SingleOrDefault(x => string.Equals(x.ApiFootballKey, feedRound, StringComparison.InvariantCultureIgnoreCase)); if (dbRound == null) { dbRound = new CompetitionSeasonRound { CompetitionSeasonId = dbCompetitionSeason.CompetitionSeasonId, RoundName = feedRound, ApiFootballKey = feedRound }; hasUpdates = true; dbRounds.Add(dbRound); dbContext.CompetitionSeasonRounds.Add(dbRound); } } if (hasUpdates) { dbContext.SaveChanges(); } }
public override void Run() { SoccerDataContext context = null; DateTime startTime = DateTime.Now; int?cacheLength = 1; var config = GetConfig(); context = new SoccerDataContext(config); //var bookmakersProcessor = new Processors.ApiFootball.Processors.OddsBookmakersProcessor(cacheLength); //bookmakersProcessor.Run(context); var oddsLabelsProcessor = new Processors.ApiFootball.Processors.OddsLabelsProcessor(cacheLength); oddsLabelsProcessor.Run(context); }
public void Run(SoccerDataContext dbContext) { var url = Feeds.OddsBookmakersFeed.GetFeedUrl(); var rawJson = JsonUtility.GetRawJsonFromUrl(url); var feed = Feeds.OddsBookmakersFeed.FromJson(rawJson); var dbBookmakersDict = dbContext.Bookmakers.ToDictionary(x => x.ApiFootballId, y => y); var apiBookmakers = feed.Result?.Bookmakers; bool hasChange = false; if (apiBookmakers != null && apiBookmakers.Count > 0) { foreach (var apiBookmaker in apiBookmakers) { if (!dbBookmakersDict.TryGetValue(apiBookmaker.Id, out Bookmaker dbBookmaker)) { dbBookmaker = new Bookmaker { ApiFootballId = apiBookmaker.Id, ApiFootballName = apiBookmaker.Name, BookmakerName = apiBookmaker.Name }; dbBookmakersDict.Add(apiBookmaker.Id, dbBookmaker); dbContext.Bookmakers.Add(dbBookmaker); hasChange = true; } else { if (dbBookmaker.ApiFootballName != apiBookmaker.Name) { dbBookmaker.ApiFootballName = apiBookmaker.Name; hasChange = true; } } } } if (hasChange) { dbContext.SaveChanges(); } }
public void Run(SoccerDataContext dbContext) { var url = Feeds.TeamFeed.GetFeedUrlByTeamId(this.ApiFootballTeamId); var rawJson = JsonUtility.GetRawJsonFromUrl(url); var feed = Feeds.TeamFeed.FromJson(rawJson); if (feed?.Result == null || feed.Result.Count == 0) { throw new ArgumentException($"TEAM DOES NOT EXIST IN API: {this.ApiFootballTeamId}"); } var feedTeam = feed.Result.Teams.Single(); var dbTeam = dbContext.Teams.SingleOrDefault(x => x.ApiFootballId == this.ApiFootballTeamId); if (dbTeam == null) { dbTeam = new Team { ApiFootballId = this.ApiFootballTeamId, CountryName = feedTeam.Country, LogoUrl = feedTeam.Logo, TeamName = feedTeam.Name, YearFounded = feedTeam.Founded }; dbContext.Teams.Add(dbTeam); dbContext.SaveChanges(); } else { if (dbTeam.TeamName != feedTeam.Name || dbTeam.LogoUrl != feedTeam.Logo || (!dbTeam.YearFounded.HasValue && feedTeam.Founded.HasValue)) { dbTeam.TeamName = feedTeam.Name; dbTeam.LogoUrl = feedTeam.Logo; dbTeam.YearFounded = feedTeam.Founded; dbContext.SaveChanges(); } } }
public void Run(SoccerDataContext dbContext) { var url = Feeds.OddsLabelsFeed.GetFeedUrl(); var rawJson = JsonUtility.GetRawJsonFromUrl(url); var feed = Feeds.OddsLabelsFeed.FromJson(rawJson); var dbLabelsDict = dbContext.OddsLabels.ToDictionary(x => x.ApiFootballId, y => y); var apiOddsLabels = feed.Result?.OddsLabels; bool hasChange = false; if (apiOddsLabels != null && apiOddsLabels.Count > 0) { foreach (var apiOddsLabel in apiOddsLabels) { if (!dbLabelsDict.TryGetValue(apiOddsLabel.Id, out OddsLabel dbOddsLabel)) { dbOddsLabel = new OddsLabel { ApiFootballId = apiOddsLabel.Id, ApiFootballName = apiOddsLabel.Name, OddsLabelName = apiOddsLabel.Name }; dbLabelsDict.Add(apiOddsLabel.Id, dbOddsLabel); dbContext.OddsLabels.Add(dbOddsLabel); dbContext.SaveChanges(); } else { if (dbOddsLabel.ApiFootballName != apiOddsLabel.Name) { dbOddsLabel.ApiFootballName = apiOddsLabel.Name; dbContext.SaveChanges(); } } } } }
public void Run(SoccerDataContext dbContext) { var url = Feeds.LeaguesFeed.GetFeedUrl(); var rawJson = JsonUtility.GetRawJsonFromUrl(url); var feed = Feeds.LeaguesFeed.FromJson(rawJson); var orderedApiLeagues = feed.Result.Leagues.OrderBy(x => x.CountryCode).ThenBy(x => x.Name).ThenBy(x => x.Season).ToList(); var existingCompetitions = dbContext.Competitions.Include(x => x.Country).ToDictionary(x => GetCompetitionKey(x), y => y); var existingCompetitionSeasons = dbContext.CompetitionSeasons.ToDictionary(x => x.ApiFootballId); var countryDict = dbContext.Countries.ToDictionary(x => x.ApiFootballCountryName, y => y.CountryId); bool isChanged = false; foreach (var apiLeague in orderedApiLeagues) { var key = GetCompetitionKey(apiLeague); if (!existingCompetitions.TryGetValue(key, out Competition dbCompetition)) { dbCompetition = new Competition { CompetitionName = apiLeague.Name.Trim(), CompetitionType = apiLeague.Type.Trim(), CountryId = countryDict[apiLeague.Country], LogoUrl = apiLeague.Logo?.ToString() }; existingCompetitions.Add(key, dbCompetition); dbContext.Competitions.Add(dbCompetition); isChanged = true; } } if (isChanged) { dbContext.SaveChanges(); isChanged = false; } foreach (var apiLeague in orderedApiLeagues) { var key = GetCompetitionKey(apiLeague); if (!existingCompetitions.TryGetValue(key, out Competition dbCompetition)) { // KEY SHOULD HAVE BEEN ADDED ABOVE throw new Exception("SOMEHOW THE COMPETITION IS NOT IN THE DB?!?!"); } if (!existingCompetitionSeasons.ContainsKey(apiLeague.LeagueId)) { var dbCompetitionSeason = new CompetitionSeason { ApiFootballId = apiLeague.LeagueId, CompetitionId = dbCompetition.CompetitionId, EndDate = apiLeague.SeasonEnd, HasFixtureEvents = apiLeague.Coverage.Fixtures.Events, HasLineups = apiLeague.Coverage.Fixtures.Lineups, HasOdds = apiLeague.Coverage.Odds, HasPlayers = apiLeague.Coverage.Players, HasPlayerStats = apiLeague.Coverage.Fixtures.PlayersStatistics, HasPredictions = apiLeague.Coverage.Predictions, HasStandings = apiLeague.Standings, HasTeamStats = apiLeague.Coverage.Fixtures.TeamStatistics, HasTopScorers = apiLeague.Coverage.TopScorers, IsCurrent = apiLeague.IsCurrent, Season = apiLeague.Season, StartDate = apiLeague.SeasonStart }; existingCompetitionSeasons.Add(apiLeague.LeagueId, dbCompetitionSeason); if (dbCompetition.CompetitionSeasons == null) { dbCompetition.CompetitionSeasons = new List <CompetitionSeason>(); } dbCompetition.CompetitionSeasons.Add(dbCompetitionSeason); isChanged = true; } } if (isChanged) { dbContext.SaveChanges(); } }
public override void Run() { SoccerDataContext context = null; DateTime startTime = DateTime.Now; int?cacheLength = 1; var config = GetConfig(); context = new SoccerDataContext(config); var countriesProcessor = new Processors.ApiFootball.Processors.CountriesProcessor(cacheLength); countriesProcessor.Run(context); var leaguesProcessor = new Processors.ApiFootball.Processors.LeaguesProcessor(cacheLength); leaguesProcessor.Run(context); var apiTransferTeamIds = new List <int>(); // ALWAYS VERIFY GAMES IN PAST 5 DAYS AND IN UPCOMING 2 DAYS int futureDaysToGet = 2; int pastDaysToGet = 5; var apiUpdatedFixtureIds = context.Fixtures .Where(x => x.GameTimeUtc.HasValue && x.GameTimeUtc.Value.AddDays(pastDaysToGet).Date > DateTime.UtcNow.Date && x.GameTimeUtc.Value.AddDays(-futureDaysToGet).Date <= DateTime.UtcNow.Date) .Select(x => x.ApiFootballId) .ToList(); // SEASON IS CURRENT IF IsCurrent AND SEASON ENDS IN FUTURE OR IN PAST 14 DAYS var dbCompetitionSeasons = context.CompetitionSeasons .Include(x => x.TeamSeasons) .ThenInclude(y => y.Team) .Where(x => x.IsCurrent && x.EndDate.HasValue && x.EndDate.Value.AddDays(14).Date >= DateTime.UtcNow.Date) .ToList(); for (int i = 0; i < dbCompetitionSeasons.Count; i++) { var dbCompetitionSeason = dbCompetitionSeasons[i]; Console.WriteLine($"DAILY COMPETITION SEASON UPDATES - {i + 1} OF {dbCompetitionSeasons.Count}"); context = new SoccerDataContext(config); //var teamsProcessor = new Processors.ApiFootball.Processors.TeamsProcessor(dbCompetitionSeason.CompetitionSeasonId, cacheLengthSec: cacheLength); //teamsProcessor.Run(context); //var apiTeamIds = dbCompetitionSeason.TeamSeasons.Select(x => x.Team.ApiFootballId).ToList(); //for (int j = 0; j < apiTeamIds.Count; j++) //{ // Console.WriteLine($"DAILY COMPETITION SEASON UPDATES - {i + 1} OF {dbCompetitionSeasons.Count} - TEAM SQUAD {j + 1} OF {apiTeamIds.Count}"); // var apiTeamId = apiTeamIds[j]; // apiTransferTeamIds.Add(apiTeamId); // var teamSquadProcessor = new Processors.ApiFootball.Processors.TeamSquadProcessor(apiTeamId, dbCompetitionSeason, cacheLengthSec: cacheLength); // teamSquadProcessor.Run(context); //} //context = new SoccerDataContext(config); var fixtureLastUpdatedDict_Start = context.Fixtures .Where(x => x.CompetitionSeasonId == dbCompetitionSeason.CompetitionSeasonId) .ToDictionary(x => x.ApiFootballId, y => y.DateLastModifiedUtc); var fixturesProcessor = new Processors.ApiFootball.Processors.LeagueFixturesProcessor(dbCompetitionSeason.CompetitionSeasonId, cacheLengthSec: cacheLength); fixturesProcessor.Run(context); var fixtureLastUpdatedDict_End = context.Fixtures .Where(x => x.CompetitionSeasonId == dbCompetitionSeason.CompetitionSeasonId) .ToDictionary(x => x.ApiFootballId, y => y.DateLastModifiedUtc); foreach (var fixtureUpdateEntry_End in fixtureLastUpdatedDict_End) { if (!fixtureLastUpdatedDict_Start.TryGetValue(fixtureUpdateEntry_End.Key, out DateTime startLastUpdateUtc) || startLastUpdateUtc != fixtureUpdateEntry_End.Value) { apiUpdatedFixtureIds.Add(fixtureUpdateEntry_End.Key); } } } apiUpdatedFixtureIds = apiUpdatedFixtureIds.Distinct().ToList(); for (int i = 0; i < apiUpdatedFixtureIds.Count; i++) { if (i % 5 == 4) { context = new SoccerDataContext(config); } var apiFixtureId = apiUpdatedFixtureIds[i]; Console.WriteLine($"DAILY FIXTURE UPDATES - {i + 1} OF {apiUpdatedFixtureIds.Count}"); var fixtureProcessor = new Processors.ApiFootball.Processors.FixtureProcessor(apiFixtureId, cacheLengthSec: cacheLength); fixtureProcessor.Run(context); var teamFixtureStatsProcessor = new Processors.ApiFootball.Processors.FixtureTeamStatsProcessor(apiFixtureId, cacheLengthSec: cacheLength); teamFixtureStatsProcessor.Run(context); var apiFootballPredictionsProcessor = new Processors.ApiFootball.Processors.ApiFootballPredictionsProcessor(apiFixtureId, cacheLengthSec: cacheLength); apiFootballPredictionsProcessor.Run(context); } apiTransferTeamIds = apiTransferTeamIds.Distinct().ToList(); for (int i = 0; i < apiTransferTeamIds.Count; i++) { if (i % 10 == 9) { context = new SoccerDataContext(config); } int apiTransferTeamId = apiTransferTeamIds[i]; Console.WriteLine($"DAILY TEAM TRANSFERS - {i + 1} OF {apiTransferTeamIds.Count}"); var transfersProcessor = new Processors.ApiFootball.Processors.TransfersProcessor(apiTransferTeamId); transfersProcessor.Run(context); } DateTime endTime = DateTime.Now; TimeSpan runLength = endTime - startTime; Console.WriteLine($"{ (runLength).TotalSeconds } SEC ({ runLength.Hours }:{ runLength.Minutes }:{ runLength.Seconds })"); Console.ReadKey(); }
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(); } }
public void Run(SoccerDataContext dbContext) { var dbCompetitionSeason = dbContext.CompetitionSeasons .Include(x => x.CompetitionSeasonRounds) .Include(x => x.Fixtures) .Include(x => x.Competition) .SingleOrDefault(x => x.CompetitionSeasonId == this.CompetitionSeasonId); if (dbCompetitionSeason == null) { return; } Console.WriteLine($"LFx-{dbCompetitionSeason.CompetitionSeasonId}-{dbCompetitionSeason.Season}-{dbCompetitionSeason.Competition.CompetitionName}"); var url = Feeds.FixturesFeed.GetFeedUrlByLeagueId(dbCompetitionSeason.ApiFootballId); var rawJson = JsonUtility.GetRawJsonFromUrl(url); var feed = Feeds.FixturesFeed.FromJson(rawJson); var teamIds = feed.Result.Fixtures.SelectMany(x => new[] { x.AwayTeam.TeamId, x.HomeTeam.TeamId }).Distinct().ToList(); var fixtureDict = dbCompetitionSeason.Fixtures.ToDictionary(x => x.ApiFootballId); var teamDict = dbContext.TeamSeasons.Include(x => x.Team).Where(x => x.CompetitionSeasonId == this.CompetitionSeasonId && teamIds.Contains(x.Team.ApiFootballId)).ToDictionary(x => x.Team.ApiFootballId, y => y.TeamSeasonId); var venueDict = dbContext.VenueSeasons.Where(x => x.Season == dbCompetitionSeason.Season).ToList(); var roundDict = dbCompetitionSeason.CompetitionSeasonRounds.ToDictionary(x => x.ApiFootballKey, y => y); var feedFixtures = feed.Result.Fixtures.Where(x => x.Status != "Match Postponed").OrderBy(x => x.EventTimestamp).ThenBy(x => x.HomeTeam?.TeamName).ToList(); #region ADD MISSING TEAMS INDIVIDUALLY (THEY ARE NOT IN THE API TEAMS LIST) var apiTeamIds = feedFixtures.SelectMany(x => new[] { x.AwayTeam.TeamId, x.HomeTeam.TeamId }).ToList(); var missingApiTeamIds = apiTeamIds.Where(x => !teamDict.ContainsKey(x)).ToList(); if (missingApiTeamIds != null && missingApiTeamIds.Count > 0) { foreach (var missingApiTeamId in missingApiTeamIds) { var dbTeam = dbContext.Teams.SingleOrDefault(x => x.ApiFootballId == missingApiTeamId); if (dbTeam == null) { var teamProcessor = new TeamProcessor(missingApiTeamId); teamProcessor.Run(dbContext); dbTeam = dbContext.Teams.SingleOrDefault(x => x.ApiFootballId == missingApiTeamId); } var dbTeamSeason = dbContext.TeamSeasons.SingleOrDefault(x => x.TeamId == dbTeam.TeamId && x.CompetitionSeasonId == this.CompetitionSeasonId); if (dbTeamSeason == null) { // CANNOT SET VENUE HERE FROM dbTeam OR API TEAM CALL BECAUSE OF POSSIBLE SEASON MISMATCH dbTeamSeason = new TeamSeason { CompetitionSeasonId = this.CompetitionSeasonId, TeamId = dbTeam.TeamId, LogoUrl = dbTeam.LogoUrl, Season = dbCompetitionSeason.Season, TeamName = dbTeam.TeamName }; dbContext.TeamSeasons.Add(dbTeamSeason); dbContext.SaveChanges(); teamDict.Add(dbTeam.ApiFootballId, dbTeamSeason.TeamSeasonId); } } } #endregion ADD MISSING TEAMS INDIVIDUALLY for (int i = 0; i < feedFixtures.Count; i++) { var feedFixture = feedFixtures[i]; if (!fixtureDict.TryGetValue(feedFixture.FixtureId, out Fixture dbFixture)) { if (!roundDict.TryGetValue(feedFixture.Round, out CompetitionSeasonRound dbRound)) { dbRound = new CompetitionSeasonRound { ApiFootballKey = feedFixture.Round, CompetitionSeason = dbCompetitionSeason, RoundName = feedFixture.Round }; dbContext.CompetitionSeasonRounds.Add(dbRound); roundDict.Add(dbRound.ApiFootballKey, dbRound); } dbFixture = new Fixture { ApiFootballId = feedFixture.FixtureId, CompetitionSeasonId = dbCompetitionSeason.CompetitionSeasonId, CompetitionSeasonRound = dbRound }; fixtureDict.Add(feedFixture.FixtureId, dbFixture); dbContext.Fixtures.Add(dbFixture); } // ALLOW TEAMS TO CHANGE UNTIL GAME STARTS // ASSUME TEAMS ARE POPULATED FROM TeamsFeed #region TEAMS if (!dbFixture.HomeTeamSeasonId.HasValue || !dbFixture.AwayTeamSeasonId.HasValue || (feedFixture.HomeTeam?.TeamId != null && dbFixture.HomeTeamSeason?.Team != null && dbFixture.HomeTeamSeason.Team.ApiFootballId != feedFixture.HomeTeam.TeamId) || (feedFixture.AwayTeam?.TeamId != null && dbFixture.AwayTeamSeason?.Team != null && dbFixture.AwayTeamSeason.Team.ApiFootballId != feedFixture.AwayTeam.TeamId)) { if (feedFixture.HomeTeam != null) { int homeTeamSeasonId = teamDict[feedFixture.HomeTeam.TeamId]; if (dbFixture.HomeTeamSeasonId != homeTeamSeasonId) { dbFixture.HomeTeamSeasonId = homeTeamSeasonId; } } if (feedFixture.AwayTeam != null) { int awayTeamSeasonId = teamDict[feedFixture.AwayTeam.TeamId]; if (dbFixture.AwayTeamSeasonId != awayTeamSeasonId) { dbFixture.AwayTeamSeasonId = awayTeamSeasonId; } } } #endregion TEAMS FixturesProcessorHelper.SetFixtureProperties(feedFixture, ref dbFixture); FixturesProcessorHelper.SetScoringProperties(feedFixture, ref dbFixture); } dbContext.SaveChanges(); }
public void Run(SoccerDataContext dbContext) { if (!this.DbCompetitionSeason.StartDate.HasValue || !this.DbCompetitionSeason.EndDate.HasValue) { // NULL DATES INDICATES NO GAMES YET. return; } if (this.DbCompetitionSeason == null) { this.DbCompetitionSeason = dbContext.CompetitionSeasons.Single(x => x.ApiFootballId == this.ApiFootballLeagueId); } var url = Feeds.TeamSquadFeed.GetUrlFromTeamIdAndSeasonYears(this.ApiFootballTeamId, this.DbCompetitionSeason.StartDate.Value, this.DbCompetitionSeason.EndDate.Value); var rawJson = JsonUtility.GetRawJsonFromUrl(url); var feed = Feeds.TeamSquadFeed.FromJson(rawJson); if (feed == null || feed.Result.Count == 0) { return; } int dbCompetitionSeasonId = this.DbCompetitionSeason.CompetitionSeasonId; var apiPlayerIds = feed.Result.Players.Select(x => x.PlayerId).ToList(); var playerDict = dbContext.Players.Where(x => apiPlayerIds.Contains(x.ApiFootballId)).ToDictionary(x => x.ApiFootballId, y => y); var playerSeasonDict = dbContext.PlayerSeasons.Where(x => x.CompetitionSeasonId == dbCompetitionSeasonId && apiPlayerIds.Contains(x.Player.ApiFootballId)).ToDictionary(x => x.Player.ApiFootballId, y => y); bool hasUpdate = false; var apiPlayers = feed.Result.Players.ToList(); foreach (var apiPlayer in apiPlayers) { bool isNewPlayer = false; PlayerSeason dbPlayerSeason = null; if (!playerDict.TryGetValue(apiPlayer.PlayerId, out Player dbPlayer)) { dbPlayerSeason = new PlayerSeason { CompetitionSeasonId = this.DbCompetitionSeason.CompetitionSeasonId, Height = apiPlayer.HeightInCm, JerseyNumber = apiPlayer.Number, Position = apiPlayer.Position, Weight = apiPlayer.WeightInKg }; dbPlayer = new Player { ApiFootballId = apiPlayer.PlayerId, BirthCity = apiPlayer.BirthPlace, BirthCountry = apiPlayer.BirthCountry, DateOfBirth = apiPlayer.BirthDate, FirstName = apiPlayer.Firstname, LastName = apiPlayer.Lastname, Nationality = apiPlayer.Nationality, PlayerName = apiPlayer.PlayerName, ApiFootballName = apiPlayer.PlayerName, PlayerSeasons = new List <PlayerSeason> { dbPlayerSeason } }; playerDict.Add(apiPlayer.PlayerId, dbPlayer); playerSeasonDict.Add(apiPlayer.PlayerId, dbPlayerSeason); dbContext.Players.Add(dbPlayer); hasUpdate = true; isNewPlayer = true; } if (!isNewPlayer) { if ((!string.IsNullOrEmpty(apiPlayer.BirthPlace) && dbPlayer.BirthCity != apiPlayer.BirthPlace) || (!string.IsNullOrEmpty(apiPlayer.BirthCountry) && dbPlayer.BirthCountry != apiPlayer.BirthCountry) || (apiPlayer.BirthDate.HasValue && dbPlayer.DateOfBirth != apiPlayer.BirthDate) || (!string.IsNullOrEmpty(apiPlayer.Firstname) && dbPlayer.FirstName != apiPlayer.Firstname) || (!string.IsNullOrEmpty(apiPlayer.Lastname) && dbPlayer.LastName != apiPlayer.Lastname) || (!string.IsNullOrEmpty(apiPlayer.PlayerName) && dbPlayer.ApiFootballName != apiPlayer.PlayerName) || (!string.IsNullOrEmpty(apiPlayer.Nationality) && dbPlayer.Nationality != apiPlayer.Nationality)) { // ALLOW PlayerName TO BE UPDATED AND NOT OVERWRITTEN dbPlayer.ApiFootballId = apiPlayer.PlayerId; dbPlayer.BirthCity = apiPlayer.BirthPlace; dbPlayer.BirthCountry = apiPlayer.BirthCountry; dbPlayer.DateOfBirth = apiPlayer.BirthDate; dbPlayer.FirstName = apiPlayer.Firstname; dbPlayer.LastName = apiPlayer.Lastname; dbPlayer.Nationality = apiPlayer.Nationality; dbPlayer.ApiFootballName = apiPlayer.PlayerName; if (string.IsNullOrEmpty(dbPlayer.PlayerName) && !string.IsNullOrEmpty(apiPlayer.PlayerName)) { dbPlayer.PlayerName = apiPlayer.PlayerName; } hasUpdate = true; } if (!playerSeasonDict.TryGetValue(apiPlayer.PlayerId, out dbPlayerSeason)) { dbPlayerSeason = new PlayerSeason { CompetitionSeasonId = this.DbCompetitionSeason.CompetitionSeasonId, Height = apiPlayer.HeightInCm, JerseyNumber = apiPlayer.Number, PlayerId = dbPlayer.PlayerId, Position = apiPlayer.Position, Weight = apiPlayer.WeightInKg }; playerSeasonDict.Add(dbPlayer.ApiFootballId, dbPlayerSeason); dbContext.PlayerSeasons.Add(dbPlayerSeason); hasUpdate = true; } else if ((apiPlayer.WeightInKg.HasValue && apiPlayer.WeightInKg != dbPlayerSeason.Weight) || (apiPlayer.HeightInCm.HasValue && apiPlayer.HeightInCm != dbPlayerSeason.Height) || (apiPlayer.Number.HasValue && apiPlayer.Number != dbPlayerSeason.JerseyNumber) || (!string.IsNullOrEmpty(apiPlayer.Position) && apiPlayer.Position != dbPlayerSeason.Position)) { dbPlayerSeason.Weight = apiPlayer.WeightInKg; dbPlayerSeason.Height = apiPlayer.HeightInCm; dbPlayerSeason.JerseyNumber = apiPlayer.Number; dbPlayerSeason.Position = apiPlayer.Position; hasUpdate = true; } } } if (hasUpdate) { dbContext.SaveChanges(); } }
static void Main(string[] args) { Console.WriteLine("Hello World!"); var config = GetConfig(); var context = new SoccerDataContext(config); //var init = new SoccerDataContextInitializer(); //init.InitializeDatabase(context); var countriesProcessor = new CountriesProcessor(); Console.WriteLine("START COUNTRIES"); countriesProcessor.Run(context); Console.WriteLine("SAVE COUNTRIES"); context.SaveChanges(); Console.WriteLine("END COUNTRIES"); var leaguesProcessor = new LeaguesProcessor(); Console.WriteLine("START LEAGUES"); leaguesProcessor.Run(context); Console.WriteLine("SAVE LEAGUES"); context.SaveChanges(); Console.WriteLine("END LEAGUES"); var desiredLeagueIds = new List <int> { 751, 752, 51, 403, // EURO CHAMPS 1, 749, 750, // WORLD CUP 52, 31, 132, 530, 53, 32, 137, 514, // UEFA CL/EL 735, 734, 733, 732, 731, 730, 64, 30, 87, // ESP - LA LIGA 65, 33, 88, 776, // ESP - SEGUNDA 808, 973, // ESP - COPA DEL REY 499, 498, 444, 968, 502, 501, 445, 966, // AND - 1st AND 2nd 201, 200, 199, 294, // USA - MLS 521, 520, 519, 518, 522, 523 // USA - USL }; desiredLeagueIds = new List <int> { 1, 749, 750, // WORLD CUP 64, 30, 87, // ESP - LA LIGA 808, 973, // ESP - COPA DEL REY 200, 199, 294, // USA - MLS }; var competitionSeasonIds = context.CompetitionSeasons .Where(x => desiredLeagueIds.Contains(x.ApiFootballId)) .Select(x => x.CompetitionSeasonId) .Distinct() .OrderBy(x => x) .ToList(); for (int i = 0; i < competitionSeasonIds.Count; i++) { Console.WriteLine($"START LEAGUE {i+1} OF {competitionSeasonIds.Count}"); int competitionSeasonId = competitionSeasonIds[i]; if (i % 10 == 9) { Console.WriteLine("NEW CONTEXT"); context.Dispose(); context = new SoccerDataContext(config); } var teamsProcessor = new TeamsProcessor(competitionSeasonId); teamsProcessor.Run(context); var roundsProcessor = new CompetitionSeasonRoundsProcessor(competitionSeasonId); roundsProcessor.Run(context); context.SaveChanges(); var leagueFixturesProcessor = new LeagueFixturesProcessor(competitionSeasonId); leagueFixturesProcessor.Run(context); context.SaveChanges(); } var a = 1; }
public void Run(SoccerDataContext dbContext) { var dbFixture = dbContext.Fixtures.SingleOrDefault(x => x.ApiFootballId == this.ApiFootballFixtureId); if (dbFixture == null) { return; } var url = Feeds.PredictionsFeed.GetFeedUrlByFixtureId(this.ApiFootballFixtureId); var rawJson = JsonUtility.GetRawJsonFromUrl(url); if (rawJson == null) { rawJson = JsonUtility.GetRawJsonFromUrl(url); } var feed = Feeds.PredictionsFeed.FromJson(rawJson); var feedPred = feed?.Result?.Predictions?.SingleOrDefault(); if (feedPred == null) { return; } bool hasUpdate = false; var dbApiFootballPrediction = dbContext.ApiFootballPredictions.SingleOrDefault(x => x.FixtureId == dbFixture.FixtureId); if (dbApiFootballPrediction == null) { hasUpdate = true; dbApiFootballPrediction = new ApiFootballPrediction { FixtureId = dbFixture.FixtureId }; dbContext.ApiFootballPredictions.Add(dbApiFootballPrediction); } else if ( dbApiFootballPrediction.Advice != feedPred.Advice || dbApiFootballPrediction.GameTotal != feedPred.GameTotal || dbApiFootballPrediction.GoalsAwaySpread != feedPred.GoalsAway || dbApiFootballPrediction.GoalsHomeSpread != feedPred.GoalsHome || dbApiFootballPrediction.H2H_Home_AwayDraws != feedPred.Teams?.Home?.LastH2H?.Draws?.Away || dbApiFootballPrediction.H2H_Home_AwayLosses != feedPred.Teams?.Home?.LastH2H?.Losses?.Away || dbApiFootballPrediction.H2H_Home_AwayWins != feedPred.Teams?.Home?.LastH2H?.Wins?.Away || dbApiFootballPrediction.H2H_Home_HomeDraws != feedPred.Teams?.Home?.LastH2H?.Draws?.Home || dbApiFootballPrediction.H2H_Home_HomeLosses != feedPred.Teams?.Home?.LastH2H?.Losses?.Home || dbApiFootballPrediction.H2H_Home_HomeWins != feedPred.Teams?.Home?.LastH2H?.Wins?.Home || dbApiFootballPrediction.H2H_Home_TotalDraws != feedPred.Teams?.Home?.LastH2H?.Draws?.Total || dbApiFootballPrediction.H2H_Home_TotalLosses != feedPred.Teams?.Home?.LastH2H?.Losses?.Total || dbApiFootballPrediction.H2H_Home_TotalWins != feedPred.Teams?.Home?.LastH2H?.Wins?.Total || dbApiFootballPrediction.MatchWinner != feedPred.MatchWinner || dbApiFootballPrediction.Pred_Away_Attack != feedPred.Comparison?.Att?.AwayWinPct || dbApiFootballPrediction.Pred_Away_Defense != feedPred.Comparison?.Def?.AwayWinPct || dbApiFootballPrediction.Pred_Away_FishLaw != feedPred.Comparison?.FishLaw?.AwayWinPct || dbApiFootballPrediction.Pred_Away_Forme != feedPred.Comparison?.Forme?.AwayWinPct || dbApiFootballPrediction.Pred_Away_GoalsH2H != feedPred.Comparison?.GoalsH2H?.AwayWinPct || dbApiFootballPrediction.Pred_Away_H2H != feedPred.Comparison?.H2H?.AwayWinPct || dbApiFootballPrediction.Pred_Home_Attack != feedPred.Comparison?.Att?.HomeWinPct || dbApiFootballPrediction.Pred_Home_Defense != feedPred.Comparison?.Def?.HomeWinPct || dbApiFootballPrediction.Pred_Home_FishLaw != feedPred.Comparison?.FishLaw?.HomeWinPct || dbApiFootballPrediction.Pred_Home_Forme != feedPred.Comparison?.Forme?.HomeWinPct || dbApiFootballPrediction.Pred_Home_GoalsH2H != feedPred.Comparison?.GoalsH2H?.HomeWinPct || dbApiFootballPrediction.Pred_Home_H2H != feedPred.Comparison?.H2H?.HomeWinPct || dbApiFootballPrediction.RawLast5_Away_AllowedGoals != feedPred.Teams?.Away?.Last5_Matches?.GoalsAgainst || dbApiFootballPrediction.RawLast5_Away_Attack != feedPred.Teams?.Away?.Last5_Matches?.Attack || dbApiFootballPrediction.RawLast5_Away_Defense != feedPred.Teams?.Away?.Last5_Matches?.Defense || dbApiFootballPrediction.RawLast5_Away_Forme != feedPred.Teams?.Away?.Last5_Matches?.Forme || dbApiFootballPrediction.RawLast5_Away_Goals != feedPred.Teams?.Away?.Last5_Matches?.Goals || dbApiFootballPrediction.RawLast5_Home_AllowedGoals != feedPred.Teams?.Home?.Last5_Matches?.GoalsAgainst || dbApiFootballPrediction.RawLast5_Home_Attack != feedPred.Teams?.Home?.Last5_Matches?.Attack || dbApiFootballPrediction.RawLast5_Home_Defense != feedPred.Teams?.Home?.Last5_Matches?.Defense || dbApiFootballPrediction.RawLast5_Home_Forme != feedPred.Teams?.Home?.Last5_Matches?.Forme || dbApiFootballPrediction.RawLast5_Home_Goals != feedPred.Teams?.Home?.Last5_Matches?.Goals || dbApiFootballPrediction.Recent_Away_AwayAllowedGoals != feedPred.Teams?.Away?.AllLastMatches?.Goals?.GoalsAgainst?.Away || dbApiFootballPrediction.Recent_Away_AwayGoals != feedPred.Teams?.Away?.AllLastMatches?.Goals?.GoalsFor?.Away || dbApiFootballPrediction.Recent_Away_HomeAllowedGoals != feedPred.Teams?.Away?.AllLastMatches?.Goals?.GoalsAgainst?.Home || dbApiFootballPrediction.Recent_Away_HomeGoals != feedPred.Teams?.Away?.AllLastMatches?.Goals?.GoalsFor?.Home || dbApiFootballPrediction.Recent_Away_TotalAllowedGoals != feedPred.Teams?.Away?.AllLastMatches?.Goals?.GoalsAgainst?.Total || dbApiFootballPrediction.Recent_Away_TotalGoals != feedPred.Teams?.Away?.AllLastMatches?.Goals?.GoalsFor?.Total || dbApiFootballPrediction.Recent_Home_AwayAllowedGoals != feedPred.Teams?.Home?.AllLastMatches?.Goals?.GoalsAgainst?.Away || dbApiFootballPrediction.Recent_Home_AwayGoals != feedPred.Teams?.Home?.AllLastMatches?.Goals?.GoalsFor?.Away || dbApiFootballPrediction.Recent_Home_HomeAllowedGoals != feedPred.Teams?.Home?.AllLastMatches?.Goals?.GoalsAgainst?.Home || dbApiFootballPrediction.Recent_Home_HomeGoals != feedPred.Teams?.Home?.AllLastMatches?.Goals?.GoalsFor?.Home || dbApiFootballPrediction.Recent_Home_TotalAllowedGoals != feedPred.Teams?.Home?.AllLastMatches?.Goals?.GoalsAgainst?.Total || dbApiFootballPrediction.Recent_Home_TotalGoals != feedPred.Teams?.Home?.AllLastMatches?.Goals?.GoalsFor?.Total || dbApiFootballPrediction.Recent_Away_AwayWins != feedPred.Teams?.Away?.AllLastMatches?.Matches?.Wins?.Away || dbApiFootballPrediction.Recent_Away_AwayDraws != feedPred.Teams?.Away?.AllLastMatches?.Matches?.Draws?.Away || dbApiFootballPrediction.Recent_Away_AwayLosses != feedPred.Teams?.Away?.AllLastMatches?.Matches?.Losses?.Away || dbApiFootballPrediction.Recent_Away_HomeWins != feedPred.Teams?.Away?.AllLastMatches?.Matches?.Wins?.Home || dbApiFootballPrediction.Recent_Away_HomeDraws != feedPred.Teams?.Away?.AllLastMatches?.Matches?.Draws?.Home || dbApiFootballPrediction.Recent_Away_HomeLosses != feedPred.Teams?.Away?.AllLastMatches?.Matches?.Losses?.Home || dbApiFootballPrediction.Recent_Away_TotalWins != feedPred.Teams?.Away?.AllLastMatches?.Matches?.Wins?.Total || dbApiFootballPrediction.Recent_Away_TotalDraws != feedPred.Teams?.Away?.AllLastMatches?.Matches?.Draws?.Total || dbApiFootballPrediction.Recent_Away_TotalLosses != feedPred.Teams?.Away?.AllLastMatches?.Matches?.Losses?.Total || dbApiFootballPrediction.Recent_Home_AwayWins != feedPred.Teams?.Home?.AllLastMatches?.Matches?.Wins?.Away || dbApiFootballPrediction.Recent_Home_AwayDraws != feedPred.Teams?.Home?.AllLastMatches?.Matches?.Draws?.Away || dbApiFootballPrediction.Recent_Home_AwayLosses != feedPred.Teams?.Home?.AllLastMatches?.Matches?.Losses?.Away || dbApiFootballPrediction.Recent_Home_HomeWins != feedPred.Teams?.Home?.AllLastMatches?.Matches?.Wins?.Home || dbApiFootballPrediction.Recent_Home_HomeDraws != feedPred.Teams?.Home?.AllLastMatches?.Matches?.Draws?.Home || dbApiFootballPrediction.Recent_Home_HomeLosses != feedPred.Teams?.Home?.AllLastMatches?.Matches?.Losses?.Home || dbApiFootballPrediction.Recent_Home_TotalWins != feedPred.Teams?.Home?.AllLastMatches?.Matches?.Wins?.Total || dbApiFootballPrediction.Recent_Home_TotalDraws != feedPred.Teams?.Home?.AllLastMatches?.Matches?.Draws?.Total || dbApiFootballPrediction.Recent_Home_TotalLosses != feedPred.Teams?.Home?.AllLastMatches?.Matches?.Losses?.Total || dbApiFootballPrediction.WinPctAway != feedPred.WinningPercent?.Away || dbApiFootballPrediction.WinPctDraw != feedPred.WinningPercent?.Draw || dbApiFootballPrediction.WinPctHome != feedPred.WinningPercent?.Home) { hasUpdate = true; } if (hasUpdate) { dbApiFootballPrediction.Advice = feedPred.Advice; dbApiFootballPrediction.GameTotal = feedPred.GameTotal; dbApiFootballPrediction.GoalsAwaySpread = feedPred.GoalsAway; dbApiFootballPrediction.GoalsHomeSpread = feedPred.GoalsHome; dbApiFootballPrediction.H2H_Home_AwayDraws = feedPred.Teams?.Home?.LastH2H?.Draws?.Away; dbApiFootballPrediction.H2H_Home_AwayLosses = feedPred.Teams?.Home?.LastH2H?.Losses?.Away; dbApiFootballPrediction.H2H_Home_AwayWins = feedPred.Teams?.Home?.LastH2H?.Wins?.Away; dbApiFootballPrediction.H2H_Home_HomeDraws = feedPred.Teams?.Home?.LastH2H?.Draws?.Home; dbApiFootballPrediction.H2H_Home_HomeLosses = feedPred.Teams?.Home?.LastH2H?.Losses?.Home; dbApiFootballPrediction.H2H_Home_HomeWins = feedPred.Teams?.Home?.LastH2H?.Wins?.Home; dbApiFootballPrediction.H2H_Home_TotalDraws = feedPred.Teams?.Home?.LastH2H?.Draws?.Total; dbApiFootballPrediction.H2H_Home_TotalLosses = feedPred.Teams?.Home?.LastH2H?.Losses?.Total; dbApiFootballPrediction.H2H_Home_TotalWins = feedPred.Teams?.Home?.LastH2H?.Wins?.Total; dbApiFootballPrediction.MatchWinner = feedPred.MatchWinner; dbApiFootballPrediction.Pred_Away_Attack = feedPred.Comparison?.Att?.AwayWinPct; dbApiFootballPrediction.Pred_Away_Defense = feedPred.Comparison?.Def?.AwayWinPct; dbApiFootballPrediction.Pred_Away_FishLaw = feedPred.Comparison?.FishLaw?.AwayWinPct; dbApiFootballPrediction.Pred_Away_Forme = feedPred.Comparison?.Forme?.AwayWinPct; dbApiFootballPrediction.Pred_Away_GoalsH2H = feedPred.Comparison?.GoalsH2H?.AwayWinPct; dbApiFootballPrediction.Pred_Away_H2H = feedPred.Comparison?.H2H?.AwayWinPct; dbApiFootballPrediction.Pred_Home_Attack = feedPred.Comparison?.Att?.HomeWinPct; dbApiFootballPrediction.Pred_Home_Defense = feedPred.Comparison?.Def?.HomeWinPct; dbApiFootballPrediction.Pred_Home_FishLaw = feedPred.Comparison?.FishLaw?.HomeWinPct; dbApiFootballPrediction.Pred_Home_Forme = feedPred.Comparison?.Forme?.HomeWinPct; dbApiFootballPrediction.Pred_Home_GoalsH2H = feedPred.Comparison?.GoalsH2H?.HomeWinPct; dbApiFootballPrediction.Pred_Home_H2H = feedPred.Comparison?.H2H?.HomeWinPct; dbApiFootballPrediction.RawLast5_Away_AllowedGoals = feedPred.Teams?.Away?.Last5_Matches?.GoalsAgainst; dbApiFootballPrediction.RawLast5_Away_Attack = feedPred.Teams?.Away?.Last5_Matches?.Attack; dbApiFootballPrediction.RawLast5_Away_Defense = feedPred.Teams?.Away?.Last5_Matches?.Defense; dbApiFootballPrediction.RawLast5_Away_Forme = feedPred.Teams?.Away?.Last5_Matches?.Forme; dbApiFootballPrediction.RawLast5_Away_Goals = feedPred.Teams?.Away?.Last5_Matches?.Goals; dbApiFootballPrediction.RawLast5_Home_AllowedGoals = feedPred.Teams?.Home?.Last5_Matches?.GoalsAgainst; dbApiFootballPrediction.RawLast5_Home_Attack = feedPred.Teams?.Home?.Last5_Matches?.Attack; dbApiFootballPrediction.RawLast5_Home_Defense = feedPred.Teams?.Home?.Last5_Matches?.Defense; dbApiFootballPrediction.RawLast5_Home_Forme = feedPred.Teams?.Home?.Last5_Matches?.Forme; dbApiFootballPrediction.RawLast5_Home_Goals = feedPred.Teams?.Home?.Last5_Matches?.Goals; dbApiFootballPrediction.Recent_Away_AwayAllowedGoals = feedPred.Teams?.Away?.AllLastMatches?.Goals?.GoalsAgainst?.Away; dbApiFootballPrediction.Recent_Away_AwayGoals = feedPred.Teams?.Away?.AllLastMatches?.Goals?.GoalsFor?.Away; dbApiFootballPrediction.Recent_Away_HomeAllowedGoals = feedPred.Teams?.Away?.AllLastMatches?.Goals?.GoalsAgainst?.Home; dbApiFootballPrediction.Recent_Away_HomeGoals = feedPred.Teams?.Away?.AllLastMatches?.Goals?.GoalsFor?.Home; dbApiFootballPrediction.Recent_Away_TotalAllowedGoals = feedPred.Teams?.Away?.AllLastMatches?.Goals?.GoalsAgainst?.Total; dbApiFootballPrediction.Recent_Away_TotalGoals = feedPred.Teams?.Away?.AllLastMatches?.Goals?.GoalsFor?.Total; dbApiFootballPrediction.Recent_Home_AwayAllowedGoals = feedPred.Teams?.Home?.AllLastMatches?.Goals?.GoalsAgainst?.Away; dbApiFootballPrediction.Recent_Home_AwayGoals = feedPred.Teams?.Home?.AllLastMatches?.Goals?.GoalsFor?.Away; dbApiFootballPrediction.Recent_Home_HomeAllowedGoals = feedPred.Teams?.Home?.AllLastMatches?.Goals?.GoalsAgainst?.Home; dbApiFootballPrediction.Recent_Home_HomeGoals = feedPred.Teams?.Home?.AllLastMatches?.Goals?.GoalsFor?.Home; dbApiFootballPrediction.Recent_Home_TotalAllowedGoals = feedPred.Teams?.Home?.AllLastMatches?.Goals?.GoalsAgainst?.Total; dbApiFootballPrediction.Recent_Home_TotalGoals = feedPred.Teams?.Home?.AllLastMatches?.Goals?.GoalsFor?.Total; dbApiFootballPrediction.Recent_Away_AwayWins = feedPred.Teams?.Away?.AllLastMatches?.Matches?.Wins?.Away; dbApiFootballPrediction.Recent_Away_AwayDraws = feedPred.Teams?.Away?.AllLastMatches?.Matches?.Draws?.Away; dbApiFootballPrediction.Recent_Away_AwayLosses = feedPred.Teams?.Away?.AllLastMatches?.Matches?.Losses?.Away; dbApiFootballPrediction.Recent_Away_HomeWins = feedPred.Teams?.Away?.AllLastMatches?.Matches?.Wins?.Home; dbApiFootballPrediction.Recent_Away_HomeDraws = feedPred.Teams?.Away?.AllLastMatches?.Matches?.Draws?.Home; dbApiFootballPrediction.Recent_Away_HomeLosses = feedPred.Teams?.Away?.AllLastMatches?.Matches?.Losses?.Home; dbApiFootballPrediction.Recent_Away_TotalWins = feedPred.Teams?.Away?.AllLastMatches?.Matches?.Wins?.Total; dbApiFootballPrediction.Recent_Away_TotalDraws = feedPred.Teams?.Away?.AllLastMatches?.Matches?.Draws?.Total; dbApiFootballPrediction.Recent_Away_TotalLosses = feedPred.Teams?.Away?.AllLastMatches?.Matches?.Losses?.Total; dbApiFootballPrediction.Recent_Home_AwayWins = feedPred.Teams?.Home?.AllLastMatches?.Matches?.Wins?.Away; dbApiFootballPrediction.Recent_Home_AwayDraws = feedPred.Teams?.Home?.AllLastMatches?.Matches?.Draws?.Away; dbApiFootballPrediction.Recent_Home_AwayLosses = feedPred.Teams?.Home?.AllLastMatches?.Matches?.Losses?.Away; dbApiFootballPrediction.Recent_Home_HomeWins = feedPred.Teams?.Home?.AllLastMatches?.Matches?.Wins?.Home; dbApiFootballPrediction.Recent_Home_HomeDraws = feedPred.Teams?.Home?.AllLastMatches?.Matches?.Draws?.Home; dbApiFootballPrediction.Recent_Home_HomeLosses = feedPred.Teams?.Home?.AllLastMatches?.Matches?.Losses?.Home; dbApiFootballPrediction.Recent_Home_TotalWins = feedPred.Teams?.Home?.AllLastMatches?.Matches?.Wins?.Total; dbApiFootballPrediction.Recent_Home_TotalDraws = feedPred.Teams?.Home?.AllLastMatches?.Matches?.Draws?.Total; dbApiFootballPrediction.Recent_Home_TotalLosses = feedPred.Teams?.Home?.AllLastMatches?.Matches?.Losses?.Total; dbApiFootballPrediction.WinPctAway = feedPred.WinningPercent?.Away; dbApiFootballPrediction.WinPctDraw = feedPred.WinningPercent?.Draw; dbApiFootballPrediction.WinPctHome = feedPred.WinningPercent?.Home; dbContext.SaveChanges(); } }
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.FixtureTeamStatsFeed.GetFeedUrlByFixtureId(this.ApiFootballFixtureId); var rawJson = JsonUtility.GetRawJsonFromUrl(url); if (rawJson.Contains("\"results\":0,")) { if (!dbFixture.HasTeamBoxscores.HasValue) { dbFixture.HasTeamBoxscores = false; dbContext.SaveChanges(); } return; } var feed = Feeds.FixtureTeamStatsFeed.FromJson(rawJson); bool hasUpdate = false; int dbFixtureId = dbFixture.FixtureId; int dbHomeTeamSeasonId = dbFixture.HomeTeamSeasonId.Value; int dbAwayTeamSeasonId = dbFixture.AwayTeamSeasonId.Value; 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; } Dictionary <string, Feeds.FixtureTeamStatsFeed.Statistic> apiStatsDict = feed.ResultWrapper.Statistics; bool homeUpdated = false; bool awayUpdated = false; homeUpdated = PopulateTeamBoxscore(apiStatsDict, x => x.Home, ref dbHomeBoxscore); awayUpdated = PopulateTeamBoxscore(apiStatsDict, x => x.Away, ref dbAwayBoxscore); hasUpdate = hasUpdate || homeUpdated || awayUpdated; if (hasUpdate) { dbFixture.HasTeamBoxscores = true; dbFixture.DateLastModifiedUtc = DateTime.UtcNow; dbContext.SaveChanges(); } }
public void Run(SoccerDataContext dbContext) { var url = Feeds.TransfersFeed.GetUrlFromTeamId(this.ApiFootballTeamId); var rawJson = JsonUtility.GetRawJsonFromUrl(url); var feed = Feeds.TransfersFeed.FromJson(rawJson); if (feed?.Result?.Transfers == null || feed.Result.Transfers.Count == 0) { return; } // TRANSFERS NOT SUPPORTED var apiTransfers = feed.Result.Transfers.Distinct(new Feeds.TransfersFeed.ApiTransferEqualityComparer()).ToList(); #region ADD MISSING TEAMS var apiTeams = apiTransfers.SelectMany(x => new[] { x.TeamIn, x.TeamOut }) .Where(x => x.TeamId.HasValue) .Distinct(new Feeds.TransfersFeed.ApiTeamEqualityComparer()) .ToList(); var apiTeamIds = apiTeams.Select(x => x.TeamId.Value); var teamsDict = dbContext.Teams.Where(x => apiTeamIds.Contains(x.ApiFootballId)).ToDictionary(x => x.ApiFootballId, y => y.TeamId); var apiMissingTeamIds = apiTeamIds.Where(x => !teamsDict.ContainsKey(x)).ToList(); if (apiMissingTeamIds != null && apiMissingTeamIds.Count != 0) { foreach (var apiMissingTeamId in apiMissingTeamIds) { var teamProcessor = new Processors.TeamProcessor(apiMissingTeamId); teamProcessor.Run(dbContext); } dbContext.SaveChanges(); teamsDict = dbContext.Teams.Where(x => apiTeamIds.Contains(x.ApiFootballId)).ToDictionary(x => x.ApiFootballId, y => y.TeamId); } #endregion ADD MISSING TEAMS #region ADD MISSING PLAYERS var apiPlayers = apiTransfers.Select(x => new { PlayerId = x.PlayerId, PlayerName = x.PlayerName }).Distinct().ToList(); var apiPlayerIds = apiPlayers.Select(x => x.PlayerId).Distinct().ToList(); var playersDict = dbContext.Players.Where(x => apiPlayerIds.Contains(x.ApiFootballId)).ToDictionary(x => x.ApiFootballId, y => y.PlayerId); var apiMissingPlayerIds = apiPlayerIds.Where(x => !playersDict.ContainsKey(x)).ToList(); if (apiMissingPlayerIds != null && apiMissingPlayerIds.Count != 0) { foreach (var apiMissingPlayerId in apiMissingPlayerIds) { var apiPlayer = apiPlayers.First(x => x.PlayerId == apiMissingPlayerId); var dbPlayer = new Player { ApiFootballId = apiPlayer.PlayerId, ApiFootballName = apiPlayer.PlayerName, PlayerName = apiPlayer.PlayerName }; dbContext.Players.Add(dbPlayer); } dbContext.SaveChanges(); playersDict = dbContext.Players.Where(x => apiPlayerIds.Contains(x.ApiFootballId)).ToDictionary(x => x.ApiFootballId, y => y.PlayerId); } #endregion ADD MISSING PLAYERS var requestedTeamId = teamsDict[this.ApiFootballTeamId]; var dbTransfers = dbContext.Transfers.Where(x => x.DestTeamId == requestedTeamId || x.SourceTeamId == requestedTeamId).ToList(); if (dbTransfers.Count == apiTransfers.Count) { return; } foreach (var apiTransfer in apiTransfers) { int?apiTeamOutId = apiTransfer.TeamOut?.TeamId; int?apiTeamInId = apiTransfer.TeamIn?.TeamId; var dbPlayerId = playersDict[apiTransfer.PlayerId]; var dbSourceTeamId = apiTeamOutId.HasValue ? teamsDict[apiTeamOutId.Value] : (int?)null; var dbDestTeamId = apiTeamInId.HasValue ? teamsDict[apiTeamInId.Value] : (int?)null; var dbTransfer = dbTransfers.SingleOrDefault(x => x.PlayerId == dbPlayerId && x.SourceTeamId == dbSourceTeamId && x.DestTeamId == dbDestTeamId && x.TransferDate?.Date == apiTransfer.TransferDate?.Date && x.TransferType == apiTransfer.TransferType); if (dbTransfer == null) { dbTransfer = new Transfer { DestTeamId = dbDestTeamId, SourceTeamId = dbSourceTeamId, PlayerId = dbPlayerId, TransferDate = apiTransfer.TransferDate?.Date, TransferType = apiTransfer.TransferType }; dbContext.Transfers.Add(dbTransfer); } else { dbTransfers.Remove(dbTransfer); } } if (dbTransfers.Count > 0) { dbContext.Transfers.RemoveRange(dbTransfers); } dbContext.SaveChanges(); }
public void Run(SoccerDataContext dbContext) { var dbCompetitionSeason = dbContext.CompetitionSeasons.Include(x => x.Competition.Country).SingleOrDefault(x => x.CompetitionSeasonId == this.CompetitionSeasonId); if (dbCompetitionSeason == null) { return; } Console.WriteLine($"{dbCompetitionSeason.CompetitionSeasonId}-{dbCompetitionSeason.Season}-{dbCompetitionSeason.Competition.CompetitionName}"); var url = Feeds.TeamsFeed.GetFeedUrlByLeagueId(dbCompetitionSeason.ApiFootballId); var rawJson = this.JsonUtility.GetRawJsonFromUrl(url); var feed = Feeds.TeamsFeed.FromJson(rawJson); var teamDict = dbContext.Teams.Include(x => x.TeamSeasons).ToDictionary(x => x.ApiFootballId); var venueDict = dbContext.Venues.Include(x => x.VenueSeasons) .ToDictionary(x => GetVenueKey(x.VenueName, x.VenueAddress)); var worldCountryId = dbContext.Countries.Single(x => x.ApiFootballCountryName.ToUpper() == WorldCountryName).CountryId; int competitionSeasonId = dbCompetitionSeason.CompetitionSeasonId; int competitionCountryId = dbCompetitionSeason.Competition?.CountryId ?? worldCountryId; var feedTeams = feed.Result.Teams.OrderBy(x => x.Name).ToList(); bool hasUpdates = false; foreach (var feedTeam in feed.Result.Teams) { Venue dbVenue = null; VenueSeason dbVenueSeason = null; #region VENUE SETTING string venueName = System.Web.HttpUtility.HtmlDecode(feedTeam.VenueName); string venueAddress = System.Web.HttpUtility.HtmlDecode(feedTeam.VenueAddress); string venueCity = System.Web.HttpUtility.HtmlDecode(feedTeam.VenueCity); var venueKey = GetVenueKey(venueName, venueAddress); if (!string.IsNullOrEmpty(venueKey)) { if (!venueDict.TryGetValue(venueKey, out dbVenue)) { dbVenue = new Venue { Capacity = feedTeam.VenueCapacity, SurfaceType = feedTeam.VenueSurface, VenueAddress = venueAddress, VenueCity = venueCity, VenueName = venueName, VenueNation = feedTeam.Country }; venueDict.Add(venueKey, dbVenue); dbContext.Venues.Add(dbVenue); } if (dbVenue.VenueSeasons == null) { dbVenue.VenueSeasons = new List <VenueSeason>(); } dbVenueSeason = dbVenue.VenueSeasons.SingleOrDefault(x => x.Season == dbCompetitionSeason.Season); if (dbVenueSeason == null) { dbVenueSeason = new VenueSeason { Capacity = feedTeam.VenueCapacity, Season = dbCompetitionSeason.Season, VenueName = venueName, SurfaceType = feedTeam.VenueSurface }; dbVenue.VenueSeasons.Add(dbVenueSeason); } } #endregion VENUE SETTING if (!teamDict.TryGetValue(feedTeam.TeamId, out Team dbTeam)) { dbTeam = new Team { ApiFootballId = feedTeam.TeamId, CountryName = feedTeam.Country, LogoUrl = feedTeam.Logo.ToString(), TeamName = feedTeam.Name, YearFounded = feedTeam.Founded, TeamSeasons = new List <TeamSeason>() }; hasUpdates = true; teamDict.Add(feedTeam.TeamId, dbTeam); dbContext.Teams.Add(dbTeam); } if (dbTeam.TeamSeasons == null) { dbTeam.TeamSeasons = new List <TeamSeason>(); } var dbTeamSeason = dbTeam.TeamSeasons.SingleOrDefault(x => x.CompetitionSeasonId == competitionSeasonId); if (dbTeamSeason == null) { dbTeamSeason = new TeamSeason { CompetitionSeasonId = competitionSeasonId, LogoUrl = feedTeam.Logo.ToString(), Season = dbCompetitionSeason.Season, TeamName = feedTeam.Name, VenueSeason = dbVenueSeason }; hasUpdates = true; dbTeam.TeamSeasons.Add(dbTeamSeason); } } if (hasUpdates) { dbContext.SaveChanges(); } }
protected void Seed(SoccerDataContext context) { }
public override void Run() { Console.WriteLine("Hello World!"); SoccerDataContext context = null; DateTime startTime = DateTime.Now; try { var config = GetConfig(); context = new SoccerDataContext(config); //context.Database.EnsureDeleted(); //context.Database.EnsureCreated(); //context.SaveChanges(); //var countriesProcessor = new CountriesProcessor(); //Console.WriteLine("START COUNTRIES"); //countriesProcessor.Run(context); //Console.WriteLine("SAVE COUNTRIES"); //context.SaveChanges(); //Console.WriteLine("END COUNTRIES"); //var leaguesProcessor = new LeaguesProcessor(); //Console.WriteLine("START LEAGUES"); //leaguesProcessor.Run(context); //Console.WriteLine("SAVE LEAGUES"); //context.SaveChanges(); //Console.WriteLine("END LEAGUES"); List <int> desiredLeagueIds = null; desiredLeagueIds = new List <int> { 751, 752, 51, 403, // EURO CHAMPS 1, 749, 750, // WORLD CUP 52, 31, 132, 530, 53, 32, 137, 514, // UEFA CL/EL 735, 734, 733, 732, 731, 730, 64, 30, 87, // ESP - LA LIGA 65, 33, 88, 776, // ESP - SEGUNDA 808, 973, // ESP - COPA DEL REY 499, 498, 444, 968, 502, 501, 445, 966, // AND - 1st AND 2nd 201, 200, 199, 294, // USA - MLS 521, 520, 519, 518, 522, 523 // USA - USL }; //desiredLeagueIds = new List<int> //{ // 1, 749, 750, // WORLD CUP // 64, 30, 87, // ESP - LA LIGA // 808, 973, // ESP - COPA DEL REY // 200, 199, 294, // USA - MLS //}; desiredLeagueIds = new List <int> { 357, 82, 775 }; // 2019 BRAZIL SERIE A, 2018 CHINA SUPER LEAGUE, 2019-2020 ESP LALIGA var competitionSeasons = context.CompetitionSeasons .Include(x => x.Competition) //.Where(x => desiredLeagueIds == null || desiredLeagueIds.Contains(x.ApiFootballId)) .Where(x => x.StartDate.HasValue && /*x.StartDate.Value.Date >= new DateTime(2014, 01, 01) &&*/ x.StartDate.Value.Date < new DateTime(2016, 01, 01)) //.Where(x => (x.IsCurrent && x.Competition.CompetitionType.ToUpper() == "LEAGUE" && x.EndDate.HasValue && x.EndDate.Value.Date >= DateTime.Now.Date) && (new List<string> { "ES", "CN", "BR", "AM", "CH", "CZ", "CR", "DE", "DK", "EE", "FO", "GB", "IT", "KR", "PT", "TW" }).Contains(x.Competition.Country.CountryAbbr)) // CURRENT || (PAST FROM COUNTRIES NOT CURRENTLY CANCELLED DUE TO COVID-19) //.Where(x => (x.IsCurrent && x.EndDate.Date >= DateTime.Now.Date) || (new List<string> { "MX", "RU", "CL", "DZ", "AR", "TR", "UA", "AU", "IN", "BY", "BR", "CR", "AO", "NI", "HK", "SG" }).Contains(x.Competition.Country.CountryAbbr)) // CURRENT || (PAST FROM COUNTRIES NOT CURRENTLY CANCELLED DUE TO COVID-19) //.Where(x =>x.Season >= 2016 && (new List<string> { "MX", "RU", "TR", "AU", "BY", "BR", "AO", "NI", "HK", "SG", "DK", "PL", "PY", "CN" }).Contains(x.Competition.Country.CountryAbbr)) // (PAST FROM COUNTRIES NOT CURRENTLY CANCELLED DUE TO COVID-19) //.Where(x => x.Season >= 2016 && (new List<string> { "BY", "NI", "ES" }).Contains(x.Competition.Country.CountryAbbr)) // (PAST FROM COUNTRIES NOT CURRENTLY CANCELLED DUE TO COVID-19) //.Where(x => x.IsCurrent && x.Competition.CompetitionType.ToUpper() == "LEAGUE" && x.StartDate.HasValue && x.StartDate.Value.Date >= new DateTime(2019, 01, 01)) // (PAST FROM COUNTRIES NOT CURRENTLY CANCELLED DUE TO COVID-19) .OrderBy(x => x.CompetitionSeasonId) .ToList(); int i = 710; // REDO API LEAGUE ID 2432 List <Team> dbTeams; for (; i < competitionSeasons.Count; i++) { Console.WriteLine($"START LEAGUE {i + 1} OF {competitionSeasons.Count}"); var competitionSeason = competitionSeasons[i]; int competitionSeasonId = competitionSeason.CompetitionSeasonId; // NULL StartDate AND/OR EndDate INDICATES NO GAMES AVAILABLE... NOTHING MORE TO PROCESS if (competitionSeason.StartDate.HasValue && competitionSeason.EndDate.HasValue) { var teamsProcessor = new TeamsProcessor(competitionSeasonId); teamsProcessor.Run(context); var roundsProcessor = new CompetitionSeasonRoundsProcessor(competitionSeasonId); roundsProcessor.Run(context); var leagueFixturesProcessor = new LeagueFixturesProcessor(competitionSeasonId); leagueFixturesProcessor.Run(context); context.Dispose(); context = new SoccerDataContext(config); dbTeams = context.Teams.Where(x => x.TeamSeasons.Any(y => y.CompetitionSeasonId == competitionSeasonId)).ToList(); for (int j = 0; j < dbTeams.Count; j++) { Console.WriteLine($"LEAGUE {i + 1} OF {competitionSeasons.Count} - TEAM {j + 1} OF {dbTeams.Count}"); var dbTeam = dbTeams[j]; var teamSquadProcessor = new TeamSquadProcessor(dbTeam.ApiFootballId, competitionSeason); teamSquadProcessor.Run(context); if (j % 5 == 4) { Console.WriteLine("NEW CONTEXT"); context.Dispose(); context = new SoccerDataContext(config); } } context.Dispose(); context = new SoccerDataContext(config); var competitionSeasonFixtures = context.Fixtures.Where(x => x.CompetitionSeasonId == competitionSeasonId).ToList(); for (int j = 0; j < competitionSeasonFixtures.Count; j++) { Console.WriteLine($"LEAGUE {i + 1} OF {competitionSeasons.Count} - FIXTURE {j + 1} OF {competitionSeasonFixtures.Count} - {competitionSeason.Competition.CompetitionName} ({competitionSeason.Competition.CountryId})"); var dbFixture = competitionSeasonFixtures[j]; if (string.Equals("Match Finished", dbFixture.Status, StringComparison.CurrentCultureIgnoreCase)) { // TODO: PROCESS FIXTURE DATA (INCLUDE SETTING HasTeamBoxscores VALUE ON FIXTURE) var fixtureProcessor = new FixtureProcessor(dbFixture.ApiFootballId); fixtureProcessor.Run(context); var apiFootballPredictionsProcessor = new ApiFootballPredictionsProcessor(dbFixture.ApiFootballId); apiFootballPredictionsProcessor.Run(context); } if (j % 5 == 4) { Console.WriteLine("NEW CONTEXT"); context.Dispose(); context = new SoccerDataContext(config); } } context.SaveChanges(); } } context.SaveChanges(); var apiTeamIds = context.Teams.Select(x => x.ApiFootballId).Distinct().ToList(); i = 0; for (; i < apiTeamIds.Count; i++) { Console.WriteLine($"TRANSFERS - TEAM {i + 1} OF {apiTeamIds.Count}"); var apiTeamId = apiTeamIds[i]; var teamTransfersProcessor = new TransfersProcessor(apiTeamId); teamTransfersProcessor.Run(context); if (i % 5 == 4) { Console.WriteLine("NEW CONTEXT"); context.Dispose(); context = new SoccerDataContext(config); } } } finally { if (context != null) { context.Dispose(); } } DateTime endTime = DateTime.Now; TimeSpan runLength = endTime - startTime; Console.WriteLine($"{ (runLength).TotalSeconds } SEC ({ runLength.Hours }:{ runLength.Minutes }:{ runLength.Seconds })"); Console.ReadKey(); }