// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Linq; using Microsoft.EntityFrameworkCore; using osu.Framework.Platform; namespace osu.Game.Database { public abstract class DatabaseBackedStore { protected readonly Storage Storage; 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 Cleanup() { } } }