// Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Linq; using Microsoft.EntityFrameworkCore; using osu.Framework.Platform; namespace osu.Game.Database { public abstract class DatabaseBackedStore { protected readonly Storage Storage; /// /// Create a new instance (separate from the shared context via for performing isolated operations. /// protected readonly IDatabaseContextFactory ContextFactory; /// /// Refresh an instance potentially from a different thread with a local context-tracked instance. /// /// The object to use as a reference when negotiating a local instance. /// An optional lookup source which will be used to query and populate a freshly retrieved replacement. If not provided, the refreshed object will still be returned but will not have any includes. /// A valid EF-stored type. protected virtual void Refresh(ref T obj, IQueryable lookupSource = null) where T : class, IHasPrimaryKey { using (var usage = ContextFactory.GetForWrite()) { var context = usage.Context; if (context.Entry(obj).State != EntityState.Detached) return; var id = obj.ID; var foundObject = lookupSource?.SingleOrDefault(t => t.ID == id) ?? context.Find(id); if (foundObject != null) obj = foundObject; else context.Add(obj); } } protected DatabaseBackedStore(IDatabaseContextFactory contextFactory, Storage storage = null) { ContextFactory = contextFactory; Storage = storage; } /// /// Perform any common clean-up tasks. Should be run when idle, or whenever necessary. /// public virtual void PurgeDeletable() { } } }