mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 09:27:29 +08:00
Merge pull request #12003 from UselessToucan/ef_core_5
This commit is contained in:
commit
f3faad74d5
@ -27,8 +27,8 @@
|
|||||||
<PackageReference Include="Microsoft.NETCore.Targets" Version="5.0.0" />
|
<PackageReference Include="Microsoft.NETCore.Targets" Version="5.0.0" />
|
||||||
<PackageReference Include="System.IO.Packaging" Version="5.0.0" />
|
<PackageReference Include="System.IO.Packaging" Version="5.0.0" />
|
||||||
<PackageReference Include="ppy.squirrel.windows" Version="1.9.0.5" />
|
<PackageReference Include="ppy.squirrel.windows" Version="1.9.0.5" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.4" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.4" />
|
||||||
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
||||||
<PackageReference Include="DiscordRichPresence" Version="1.0.175" />
|
<PackageReference Include="DiscordRichPresence" Version="1.0.175" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
|
@ -56,6 +56,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
beatmaps.Add(new BeatmapInfo
|
beatmaps.Add(new BeatmapInfo
|
||||||
{
|
{
|
||||||
Ruleset = rulesets.GetRuleset(i % 4),
|
Ruleset = rulesets.GetRuleset(i % 4),
|
||||||
|
RulesetID = i % 4, // workaround for efcore 5 compatibility.
|
||||||
OnlineBeatmapID = beatmapId,
|
OnlineBeatmapID = beatmapId,
|
||||||
Length = length,
|
Length = length,
|
||||||
BPM = bpm,
|
BPM = bpm,
|
||||||
|
@ -186,6 +186,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
Metadata = metadata,
|
Metadata = metadata,
|
||||||
BaseDifficulty = new BeatmapDifficulty(),
|
BaseDifficulty = new BeatmapDifficulty(),
|
||||||
Ruleset = ruleset,
|
Ruleset = ruleset,
|
||||||
|
RulesetID = ruleset.ID.GetValueOrDefault(), // workaround for efcore 5 compatibility.
|
||||||
StarDifficulty = difficultyIndex + 1,
|
StarDifficulty = difficultyIndex + 1,
|
||||||
Version = $"SR{difficultyIndex + 1}"
|
Version = $"SR{difficultyIndex + 1}"
|
||||||
}).ToList()
|
}).ToList()
|
||||||
|
@ -911,9 +911,11 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
int length = RNG.Next(30000, 200000);
|
int length = RNG.Next(30000, 200000);
|
||||||
double bpm = RNG.NextSingle(80, 200);
|
double bpm = RNG.NextSingle(80, 200);
|
||||||
|
|
||||||
|
var ruleset = getRuleset();
|
||||||
beatmaps.Add(new BeatmapInfo
|
beatmaps.Add(new BeatmapInfo
|
||||||
{
|
{
|
||||||
Ruleset = getRuleset(),
|
Ruleset = ruleset,
|
||||||
|
RulesetID = ruleset.ID.GetValueOrDefault(), // workaround for efcore 5 compatibility.
|
||||||
OnlineBeatmapID = beatmapId,
|
OnlineBeatmapID = beatmapId,
|
||||||
Version = $"{beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss}, bpm {bpm:0.#})",
|
Version = $"{beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss}, bpm {bpm:0.#})",
|
||||||
Length = length,
|
Length = length,
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.4" />
|
||||||
<PackageReference Include="Moq" Version="4.16.1" />
|
<PackageReference Include="Moq" Version="4.16.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
|
@ -174,6 +174,8 @@ namespace osu.Game.Beatmaps
|
|||||||
if (beatmapSet.Beatmaps.Any(b => b.BaseDifficulty == null))
|
if (beatmapSet.Beatmaps.Any(b => b.BaseDifficulty == null))
|
||||||
throw new InvalidOperationException($"Cannot import {nameof(BeatmapInfo)} with null {nameof(BeatmapInfo.BaseDifficulty)}.");
|
throw new InvalidOperationException($"Cannot import {nameof(BeatmapInfo)} with null {nameof(BeatmapInfo.BaseDifficulty)}.");
|
||||||
|
|
||||||
|
beatmapSet.Requery(ContextFactory);
|
||||||
|
|
||||||
// check if a set already exists with the same online id, delete if it does.
|
// check if a set already exists with the same online id, delete if it does.
|
||||||
if (beatmapSet.OnlineBeatmapSetID != null)
|
if (beatmapSet.OnlineBeatmapSetID != null)
|
||||||
{
|
{
|
||||||
|
@ -462,6 +462,8 @@ namespace osu.Game.Database
|
|||||||
// Dereference the existing file info, since the file model will be removed.
|
// Dereference the existing file info, since the file model will be removed.
|
||||||
if (file.FileInfo != null)
|
if (file.FileInfo != null)
|
||||||
{
|
{
|
||||||
|
file.Requery(usage.Context);
|
||||||
|
|
||||||
Files.Dereference(file.FileInfo);
|
Files.Dereference(file.FileInfo);
|
||||||
|
|
||||||
// This shouldn't be required, but here for safety in case the provided TModel is not being change tracked
|
// This shouldn't be required, but here for safety in case the provided TModel is not being change tracked
|
||||||
@ -635,10 +637,12 @@ namespace osu.Game.Database
|
|||||||
{
|
{
|
||||||
using (Stream s = reader.GetStream(file))
|
using (Stream s = reader.GetStream(file))
|
||||||
{
|
{
|
||||||
|
var fileInfo = files.Add(s);
|
||||||
fileInfos.Add(new TFileModel
|
fileInfos.Add(new TFileModel
|
||||||
{
|
{
|
||||||
Filename = file.Substring(prefix.Length).ToStandardisedPath(),
|
Filename = file.Substring(prefix.Length).ToStandardisedPath(),
|
||||||
FileInfo = files.Add(s)
|
FileInfo = fileInfo,
|
||||||
|
FileInfoID = fileInfo.ID // workaround for efcore 5 compatibility.
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
71
osu.Game/Database/DatabaseWorkaroundExtensions.cs
Normal file
71
osu.Game/Database/DatabaseWorkaroundExtensions.cs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
|
namespace osu.Game.Database
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Extension methods which contain workarounds to make EFcore 5.x work with our existing (incorrect) thread safety.
|
||||||
|
/// The intention is to avoid blocking package updates while we consider the future of the database backend, with a potential backend switch imminent.
|
||||||
|
/// </summary>
|
||||||
|
public static class DatabaseWorkaroundExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Re-query the provided model to ensure it is in a sane state. This method requires explicit implementation per model type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model"></param>
|
||||||
|
/// <param name="contextFactory"></param>
|
||||||
|
public static void Requery(this IHasPrimaryKey model, IDatabaseContextFactory contextFactory)
|
||||||
|
{
|
||||||
|
switch (model)
|
||||||
|
{
|
||||||
|
case SkinInfo skinInfo:
|
||||||
|
requeryFiles(skinInfo.Files, contextFactory);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScoreInfo scoreInfo:
|
||||||
|
requeryFiles(scoreInfo.Beatmap.BeatmapSet.Files, contextFactory);
|
||||||
|
requeryFiles(scoreInfo.Files, contextFactory);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BeatmapSetInfo beatmapSetInfo:
|
||||||
|
var context = contextFactory.Get();
|
||||||
|
|
||||||
|
foreach (var beatmap in beatmapSetInfo.Beatmaps)
|
||||||
|
{
|
||||||
|
// Workaround System.InvalidOperationException
|
||||||
|
// The instance of entity type 'RulesetInfo' cannot be tracked because another instance with the same key value for {'ID'} is already being tracked.
|
||||||
|
beatmap.Ruleset = context.RulesetInfo.Find(beatmap.RulesetID);
|
||||||
|
}
|
||||||
|
|
||||||
|
requeryFiles(beatmapSetInfo.Files, contextFactory);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"{nameof(Requery)} does not have support for the provided model type", nameof(model));
|
||||||
|
}
|
||||||
|
|
||||||
|
void requeryFiles<T>(List<T> files, IDatabaseContextFactory databaseContextFactory) where T : class, INamedFileInfo
|
||||||
|
{
|
||||||
|
var dbContext = databaseContextFactory.Get();
|
||||||
|
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
Requery(file, dbContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Requery(this INamedFileInfo file, OsuDbContext dbContext)
|
||||||
|
{
|
||||||
|
// Workaround System.InvalidOperationException
|
||||||
|
// The instance of entity type 'FileInfo' cannot be tracked because another instance with the same key value for {'ID'} is already being tracked.
|
||||||
|
file.FileInfo = dbContext.FileInfo.Find(file.FileInfoID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Statistics;
|
using osu.Framework.Statistics;
|
||||||
@ -111,10 +110,10 @@ namespace osu.Game.Database
|
|||||||
{
|
{
|
||||||
base.OnConfiguring(optionsBuilder);
|
base.OnConfiguring(optionsBuilder);
|
||||||
optionsBuilder
|
optionsBuilder
|
||||||
// this is required for the time being due to the way we are querying in places like BeatmapStore.
|
.UseSqlite(connectionString,
|
||||||
// if we ever move to having consumers file their own .Includes, or get eager loading support, this could be re-enabled.
|
sqliteOptions => sqliteOptions
|
||||||
.ConfigureWarnings(warnings => warnings.Ignore(CoreEventId.IncludeIgnoredWarning))
|
.CommandTimeout(10)
|
||||||
.UseSqlite(connectionString, sqliteOptions => sqliteOptions.CommandTimeout(10))
|
.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery))
|
||||||
.UseLoggerFactory(logger.Value);
|
.UseLoggerFactory(logger.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ namespace osu.Game.Scoring
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
modsJson = null;
|
modsJson = JsonConvert.SerializeObject(value.Select(m => new DeserializedMod { Acronym = m.Acronym }));
|
||||||
mods = value;
|
mods = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,16 +86,7 @@ namespace osu.Game.Scoring
|
|||||||
[Column("Mods")]
|
[Column("Mods")]
|
||||||
public string ModsJson
|
public string ModsJson
|
||||||
{
|
{
|
||||||
get
|
get => modsJson;
|
||||||
{
|
|
||||||
if (modsJson != null)
|
|
||||||
return modsJson;
|
|
||||||
|
|
||||||
if (mods == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return modsJson = JsonConvert.SerializeObject(mods.Select(m => new DeserializedMod { Acronym = m.Acronym }));
|
|
||||||
}
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
modsJson = value;
|
modsJson = value;
|
||||||
|
@ -52,6 +52,11 @@ namespace osu.Game.Scoring
|
|||||||
this.configManager = configManager;
|
this.configManager = configManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void PreImport(ScoreInfo model)
|
||||||
|
{
|
||||||
|
model.Requery(ContextFactory);
|
||||||
|
}
|
||||||
|
|
||||||
protected override ScoreInfo CreateModel(ArchiveReader archive)
|
protected override ScoreInfo CreateModel(ArchiveReader archive)
|
||||||
{
|
{
|
||||||
if (archive == null)
|
if (archive == null)
|
||||||
|
@ -142,6 +142,11 @@ namespace osu.Game.Skinning
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void PreImport(SkinInfo model)
|
||||||
|
{
|
||||||
|
model.Requery(ContextFactory);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieve a <see cref="Skin"/> instance for the provided <see cref="SkinInfo"/>
|
/// Retrieve a <see cref="Skin"/> instance for the provided <see cref="SkinInfo"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -24,10 +24,10 @@
|
|||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.2" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.2" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="5.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="5.0.3" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="5.0.2" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="5.0.2" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.4" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="5.0.4" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.NETCore.Targets" Version="3.1.0" />
|
<PackageReference Include="Microsoft.NETCore.Targets" Version="5.0.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2021.309.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2021.309.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.211.1" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.211.1" />
|
||||||
|
@ -90,8 +90,6 @@
|
|||||||
<ItemGroup Label="Transitive Dependencies">
|
<ItemGroup Label="Transitive Dependencies">
|
||||||
<PackageReference Include="DiffPlex" Version="1.6.3" />
|
<PackageReference Include="DiffPlex" Version="1.6.3" />
|
||||||
<PackageReference Include="Humanizer" Version="2.8.26" />
|
<PackageReference Include="Humanizer" Version="2.8.26" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2021.309.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2021.309.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.28.1" />
|
<PackageReference Include="SharpCompress" Version="0.28.1" />
|
||||||
|
Loading…
Reference in New Issue
Block a user