public T Commit(TT pars = default(TT)) // Pars are the extra parameters send to the save and delete callbacks, in this way we can forward behaviors to the callbacks { object obj = _repo.BeginSave(Entity, Original, pars); T ret; using (_repo.RepoLock.WriterLock()) { ShokoContext ctx = _repo.Provider.GetContext(); if (Original == null || !IsUpdate) { ret = Entity; ctx.Add(Entity); } else { ret = Original; Entity.DeepCloneTo(Original); //Tried to be 100% atomic and failed miserably, so is 99%. //If we replace Original with Entity in cache (updating with 'this' as the model to update will not get the changes). //So this is the best effort ctx.Attach(Original); ctx.Update(Original); } Release(); if (_repo.IsCached) { _repo.Cache.Update(ret); } ctx.SaveChanges(); } _repo.EndSave(ret, obj, pars); return(ret); }
public List <T> Commit(TT pars = default(TT)) { Dictionary <T, object> savedObjects = new Dictionary <T, object>(); foreach (T t in EntityList) { savedObjects[t] = _repo.BeginSave(t, References[t], pars); } List <T> returns = new List <T>(); var updates = References.Where(a => a.Value != null).ToList(); var creates = References.Where(a => a.Value == null).ToList(); using (_repo.RepoLock.WriterLock()) { ShokoContext ctx = _repo.Provider.GetContext(); foreach (KeyValuePair <T, T> r in updates) { ctx.UpdateChanges(r.Value, r.Key); /* * r.Key.DeepCloneTo(r.Value); //Tried to be 100% atomic and failed miserably, so is 99%. * //If we replace Original with Entity in cache (updating with 'this' as the model to update will not get the changes). * //So this is the best effort * ctx.Attach(r.Value); * ctx.Update(r.Value);*/ returns.Add(r.Value); } foreach (KeyValuePair <T, T> r in creates) { ctx.Add(r.Key); returns.Add(r.Key); } Release(); if (_repo.IsCached) { returns.ForEach(_repo.Cache.Update); } ctx.SaveChanges(); ctx.DetachRange(returns); } // TODO Needs a better way to index. r.Value and r.Key are not always the same, throwing an error on indexing // At least the current references will work with this. foreach (T t in savedObjects.Keys) { if (savedObjects.ContainsKey(t)) { _repo.EndSave(t, savedObjects[t], pars); } } return(EntityList); }
public List <T> Commit(TT pars = default(TT)) { Dictionary <T, object> savedObjects = new Dictionary <T, object>(); foreach (T t in EntityList) { savedObjects[t] = _repo.BeginSave(t, References[t], pars); } List <T> returns = new List <T>(); var updates = References.Where(a => a.Value != null).ToList(); var creates = References.Where(a => a.Value == null).ToList(); using (_repo.RepoLock.WriterLock()) { ShokoContext ctx = _repo.Provider.GetContext(); foreach (KeyValuePair <T, T> r in updates) { r.Key.DeepCloneTo(r.Value); //Tried to be 100% atomic and failed miserably, so is 99%. //If we replace Original with Entity in cache (updating with 'this' as the model to update will not get the changes). //So this is the best effort ctx.Attach(r.Value); ctx.Update(r.Value); returns.Add(r.Value); } foreach (KeyValuePair <T, T> r in creates) { ctx.Add(r.Key); returns.Add(r.Key); } Release(); if (_repo.IsCached) { returns.ForEach(_repo.Cache.Update); } ctx.SaveChanges(); } foreach (T t in returns) { _repo.EndSave(t, savedObjects[t], pars); } return(EntityList); }
public List <T> Commit(TT pars = default(TT)) { Dictionary <T, object> savedobjects = new Dictionary <T, object>(); if (_delete_not_updated) { foreach (T t in _originalItems.Keys.ToList()) { if (_references.ContainsKey(t)) { _originalItems.Remove(t); } } if (_originalItems.Keys.Count > 0) { foreach (T e in _originalItems.Values) { savedobjects[e] = _repo.BeginDelete(e, pars); } ShokoContext ctx = _repo.Provider.GetContext(); ctx.AttachRange(_originalItems.Values); ctx.RemoveRange(_originalItems.Values); ctx.SaveChanges(); if (_repo.IsCached) { _originalItems.Values.ForEach(_repo.Cache.Remove); } foreach (T e in _originalItems.Values) { _repo.EndDelete(e, savedobjects[e], pars); } } } savedobjects.Clear(); List <T> returns = new List <T>(); if (_references.Count > 0) { foreach (T t in _references.Keys) { savedobjects[t] = _repo.BeginSave(t, _references[t], pars); } var updates = _references.Where(a => a.Value != null).ToList(); var creates = _references.Where(a => a.Value == null).ToList(); using (_repo.RepoLock.WriterLock()) { ShokoContext ctx = _repo.Provider.GetContext(); foreach (KeyValuePair <T, T> r in updates) { ctx.UpdateChanges(r.Value, r.Key); /* * * r.Key.DeepCloneTo(r.Value); //Tried to be 100% atomic and failed miserably, so is 99%. * //If we replace Original with Entity in cache (updating with 'this' as the model to update, will not get the changes). * //So this is the best effort * ctx.Attach(r.Value); * ctx.Update(r.Value);*/ returns.Add(r.Value); } foreach (KeyValuePair <T, T> r in creates) { ctx.Add(r.Key); returns.Add(r.Key); } if (_repo.IsCached) { returns.ForEach(_repo.Cache.Update); } ctx.SaveChanges(); ctx.DetachRange(returns); } // At least the current references will work with this. foreach (T t in savedobjects.Keys) { if (savedobjects.ContainsKey(t)) { _repo.EndSave(t, savedobjects[t], pars); } } } return(returns); }
}; //TODO Set Default public void Init(ShokoContextProvider provider, HashSet <string> cachedRepos) { ShokoContext db = provider.GetContext(); db.Database.Migrate(); _repos = new List <IRepository>(); if (cachedRepos != null) { CachedRepos = cachedRepos; } Provider = provider; JMMUser = Register <JMMUserRepository, SVR_JMMUser>(db.JMMUsers); AuthTokens = Register <AuthTokensRepository, AuthTokens>(db.AuthTokens); CloudAccount = Register <CloudAccountRepository, SVR_CloudAccount>(db.CloudAccounts); ImportFolder = Register <ImportFolderRepository, SVR_ImportFolder>(db.ImportFolders); AniDB_Anime = Register <AniDB_AnimeRepository, SVR_AniDB_Anime>(db.AniDB_Animes); AniDB_Episode = Register <AniDB_EpisodeRepository, AniDB_Episode>(db.AniDB_Episodes); AniDB_File = Register <AniDB_FileRepository, SVR_AniDB_File>(db.AniDB_Files); AniDB_Anime_Title = Register <AniDB_Anime_TitleRepository, AniDB_Anime_Title>(db.AniDB_Anime_Titles); AniDB_Anime_Tag = Register <AniDB_Anime_TagRepository, AniDB_Anime_Tag>(db.AniDB_Anime_Tags); AniDB_Tag = Register <AniDB_TagRepository, AniDB_Tag>(db.AniDB_Tags); AniDB_Episode_Title = Register <AniDB_Episode_TitleRepository, AniDB_Episode_Title>(db.AniDB_Episode_Title); CustomTag = Register <CustomTagRepository, CustomTag>(db.CustomTags); CrossRef_CustomTag = Register <CrossRef_CustomTagRepository, CrossRef_CustomTag>(db.CrossRef_CustomTags); CrossRef_File_Episode = Register <CrossRef_File_EpisodeRepository, CrossRef_File_Episode>(db.CrossRef_File_Episodes); CommandRequest = Register <CommandRequestRepository, CommandRequest>(db.CommandRequests); VideoLocal_Place = Register <VideoLocal_PlaceRepository, SVR_VideoLocal_Place>(db.VideoLocal_Places); VideoLocal = Register <VideoLocalRepository, SVR_VideoLocal>(db.VideoLocals); VideoLocal_User = Register <VideoLocal_UserRepository, VideoLocal_User>(db.VideoLocal_Users); GroupFilterCondition = Register <GroupFilterConditionRepository, GroupFilterCondition>(db.GroupFilterConditions); GroupFilter = Register <GroupFilterRepository, SVR_GroupFilter>(db.GroupFilters); AnimeEpisode = Register <AnimeEpisodeRepository, SVR_AnimeEpisode>(db.AnimeEpisodes); AnimeEpisode_User = Register <AnimeEpisode_UserRepository, SVR_AnimeEpisode_User>(db.AnimeEpisode_Users); AnimeSeries = Register <AnimeSeriesRepository, SVR_AnimeSeries>(db.AnimeSeries); AnimeSeries_User = Register <AnimeSeries_UserRepository, SVR_AnimeSeries_User>(db.AnimeSeries_Users); AnimeGroup = Register <AnimeGroupRepository, SVR_AnimeGroup>(db.AnimeGroups); AnimeGroup_User = Register <AnimeGroup_UserRepository, SVR_AnimeGroup_User>(db.AnimeGroup_Users); AniDB_Vote = Register <AniDB_VoteRepository, AniDB_Vote>(db.AniDB_Votes); TvDB_Episode = Register <TvDB_EpisodeRepository, TvDB_Episode>(db.TvDB_Episodes); TvDB_Series = Register <TvDB_SeriesRepository, TvDB_Series>(db.TvDB_Series); CrossRef_AniDB_TvDBV2 = Register <CrossRef_AniDB_TvDBV2Repository, CrossRef_AniDB_TvDBV2>(db.CrossRef_AniDB_TvDBV2); CrossRef_AniDB_TvDB_Episode = Register <CrossRef_AniDB_TvDB_EpisodeRepository, CrossRef_AniDB_TvDB_Episode>(db.CrossRef_AniDB_TvDB_Episodes); TvDB_ImagePoster = Register <TvDB_ImagePosterRepository, TvDB_ImagePoster>(db.TvDB_ImagePosters); TvDB_ImageFanart = Register <TvDB_ImageFanartRepository, TvDB_ImageFanart>(db.TvDB_ImageFanarts); TvDB_ImageWideBanner = Register <TvDB_ImageWideBannerRepository, TvDB_ImageWideBanner>(db.TvDB_ImageWideBanners); Trakt_Show = Register <Trakt_ShowRepository, Trakt_Show>(db.Trakt_Shows); Trakt_Season = Register <Trakt_SeasonRepository, Trakt_Season>(db.Trakt_Seasons); Trakt_Friend = Register <Trakt_FriendRepository, Trakt_Friend>(db.Trakt_Friends); Trakt_Episode = Register <Trakt_EpisodeRepository, Trakt_Episode>(db.Trakt_Episodes); ScheduledUpdate = Register <ScheduledUpdateRepository, ScheduledUpdate>(db.ScheduledUpdates); RenameScript = Register <RenameScriptRepository, RenameScript>(db.RenameScripts); Playlist = Register <PlaylistRepository, Playlist>(db.Playlists); MovieDB_Poster = Register <MovieDB_PosterRepository, MovieDB_Poster>(db.MovieDB_Posters); MovieDB_Fanart = Register <MovieDB_FanartRepository, MovieDB_Fanart>(db.MovieDB_Fanarts); MovieDb_Movie = Register <MovieDB_MovieRepository, MovieDB_Movie>(db.MovieDB_Movies); Language = Register <LanguageRepository, Language>(db.Languages); IgnoreAnime = Register <IgnoreAnimeRepository, IgnoreAnime>(db.IgnoreAnimes); FileNameHash = Register <FileNameHashRepository, FileNameHash>(db.FileNameHashes); FileFfdshowPreset = Register <FileFfdshowPresetRepository, FileFfdshowPreset>(db.FileFfdshowPresets); DuplicateFile = Register <DuplicateFileRepository, DuplicateFile>(db.DuplicateFiles); CrossRef_Subtitles_AniDB_File = Register <CrossRef_Subtitles_AniDB_FileRepository, CrossRef_Subtitles_AniDB_File>(db.CrossRef_Subtitles_AniDB_Files); CrossRef_Languages_AniDB_File = Register <CrossRef_Languages_AniDB_FileRepository, CrossRef_Languages_AniDB_File>(db.CrossRef_Languages_AniDB_Files); CrossRef_AniDB_TraktV2 = Register <CrossRef_AniDB_TraktV2Repository, CrossRef_AniDB_TraktV2>(db.CrossRef_AniDB_TraktV2); CrossRef_AniDB_Other = Register <CrossRef_AniDB_OtherRepository, CrossRef_AniDB_Other>(db.CrossRef_AniDB_Other); CrossRef_AniDB_MAL = Register <CrossRef_AniDB_MALRepository, CrossRef_AniDB_MAL>(db.CrossRef_AniDB_MALs); BookmarkedAnime = Register <BookmarkedAnimeRepository, BookmarkedAnime>(db.BookmarkedAnimes); AniDB_Seiyuu = Register <AniDB_SeiyuuRepository, AniDB_Seiyuu>(db.AniDB_Seiyuus); AniDB_Review = Register <AniDB_ReviewRepository, AniDB_Review>(db.AniDB_Reviews); AniDB_ReleaseGroup = Register <AniDB_ReleaseGroupRepository, AniDB_ReleaseGroup>(db.AniDB_ReleaseGroups); AniDB_Recommendation = Register <AniDB_RecommendationRepository, AniDB_Recommendation>(db.AniDB_Recommendations); AniDB_MylistStats = Register <AniDB_MylistStatsRepository, AniDB_MylistStats>(db.AniDB_MylistStats); AniDB_GroupStatus = Register <AniDB_GroupStatusRepository, AniDB_GroupStatus>(db.AniDB_GroupStatus); AniDB_Character = Register <AniDB_CharacterRepository, AniDB_Character>(db.AniDB_Characters); AniDB_Character_Seiyuu = Register <AniDB_Character_SeiyuuRepository, AniDB_Character_Seiyuu>(db.AniDB_Character_Seiyuus); AniDB_Anime_Similar = Register <AniDB_Anime_SimilarRepository, AniDB_Anime_Similar>(db.AniDB_Anime_Similars); AniDB_Anime_Review = Register <AniDB_Anime_ReviewRepository, AniDB_Anime_Review>(db.AniDB_Anime_Reviews); AniDB_Anime_Relation = Register <AniDB_Anime_RelationRepository, AniDB_Anime_Relation>(db.AniDB_Anime_Relations); AniDB_Anime_DefaultImage = Register <AniDB_Anime_DefaultImageRepository, AniDB_Anime_DefaultImage>(db.AniDB_Anime_DefaultImages); AniDB_Anime_Character = Register <AniDB_Anime_CharacterRepository, AniDB_Anime_Character>(db.AniDB_Anime_Characters); Scan = Register <ScanRepository, SVR_Scan>(db.Scans); ScanFile = Register <ScanFileRepository, ScanFile>(db.ScanFiles); AnimeStaff = Register <AnimeStaffRepository, AnimeStaff>(db.AnimeStaff); AnimeCharacter = Register <AnimeCharacterRepository, AnimeCharacter>(db.AnimeCharacter); AniDB_AnimeUpdate = Register <AniDB_AnimeUpdateRepository, AniDB_AnimeUpdate>(db.AniDB_AnimeUpdate); /************** Might need to be DEPRECATED **************/ CrossRef_AniDB_Trakt_Episode = Register <CrossRef_AniDB_Trakt_EpisodeRepository, CrossRef_AniDB_Trakt_Episode>(db.CrossRef_AniDB_Trakt_Episodes); CrossRef_AniDB_TvDB_Episode_Override = Register <CrossRef_AniDB_TvDB_Episode_OverrideRepository, CrossRef_AniDB_TvDB_Episode_Override>(db.CrossRef_AniDB_TvDB_Episode_Override); CrossRef_AniDB_TvDB = Register <CrossRef_AniDB_TvDBRepository, CrossRef_AniDB_TvDB>(db.CrossRef_AniDB_TvDB); CrossRef_Anime_Staff = Register <CrossRef_Anime_StaffRepository, CrossRef_Anime_Staff>(db.CrossRef_Anime_Staff); Adhoc = new AdhocRepository(); }