try fix uid profilepicture duplicated

This commit is contained in:
DismissedLight
2024-07-09 14:05:47 +08:00
parent a32b787352
commit 0a24e19625
3 changed files with 58 additions and 21 deletions

View File

@@ -6,7 +6,7 @@ using System.Globalization;
namespace Snap.Hutao.Core.Json.Converter;
// 此转换器无法实现无损往返 必须在反序列化后调整 Offset
internal class DateTimeOffsetConverter : JsonConverter<DateTimeOffset>
internal sealed class DateTimeOffsetConverter : JsonConverter<DateTimeOffset>
{
private const string Format = "yyyy-MM-dd HH:mm:ss";

View File

@@ -2,6 +2,7 @@
// Licensed under the MIT license.
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Snap.Hutao.Core.Database;
using Snap.Hutao.Model.Entity.Database;
using System.Linq.Expressions;
@@ -32,6 +33,24 @@ internal static class AppDbServiceExtension
return service.Execute(dbset => dbset.AddRangeAndSave(entities));
}
public static int Delete<TEntity>(this IAppDbService<TEntity> service)
where TEntity : class
{
return service.Execute(dbset => dbset.ExecuteDelete());
}
public static int Delete<TEntity>(this IAppDbService<TEntity> service, TEntity entity)
where TEntity : class
{
return service.Execute(dbset => dbset.RemoveAndSave(entity));
}
public static int Delete<TEntity>(this IAppDbService<TEntity> service, Expression<Func<TEntity, bool>> predicate)
where TEntity : class
{
return service.Execute(dbset => dbset.Where(predicate).ExecuteDelete());
}
public static TResult Query<TEntity, TResult>(this IAppDbService<TEntity> service, Func<IQueryable<TEntity>, TResult> func)
where TEntity : class
{
@@ -50,27 +69,38 @@ internal static class AppDbServiceExtension
return service.Query(query => query.SingleOrDefault(predicate));
}
public static void TransactionalExecute<TEntity>(this IAppDbService<TEntity> service, Action<DbSet<TEntity>> action)
where TEntity : class
{
using (IServiceScope scope = service.ServiceProvider.CreateScope())
{
AppDbContext appDbContext = scope.GetAppDbContext();
using (IDbContextTransaction transaction = appDbContext.Database.BeginTransaction())
{
action(appDbContext.Set<TEntity>());
transaction.Commit();
}
}
}
public static TResult TransactionalExecute<TEntity, TResult>(this IAppDbService<TEntity> service, Func<DbSet<TEntity>, TResult> func)
where TEntity : class
{
using (IServiceScope scope = service.ServiceProvider.CreateScope())
{
AppDbContext appDbContext = scope.GetAppDbContext();
using (IDbContextTransaction transaction = appDbContext.Database.BeginTransaction())
{
TResult result = func(appDbContext.Set<TEntity>());
transaction.Commit();
return result;
}
}
}
public static int Update<TEntity>(this IAppDbService<TEntity> service, TEntity entity)
where TEntity : class
{
return service.Execute(dbset => dbset.UpdateAndSave(entity));
}
public static int Delete<TEntity>(this IAppDbService<TEntity> service)
where TEntity : class
{
return service.Execute(dbset => dbset.ExecuteDelete());
}
public static int Delete<TEntity>(this IAppDbService<TEntity> service, TEntity entity)
where TEntity : class
{
return service.Execute(dbset => dbset.RemoveAndSave(entity));
}
public static int Delete<TEntity>(this IAppDbService<TEntity> service, Expression<Func<TEntity, bool>> predicate)
where TEntity : class
{
return service.Execute(dbset => dbset.Where(predicate).ExecuteDelete());
}
}

View File

@@ -20,6 +20,8 @@ internal sealed partial class ProfilePictureService : IProfilePictureService
private readonly IServiceProvider serviceProvider;
private readonly ITaskContext taskContext;
private readonly object syncRoot = new();
public async ValueTask TryInitializeAsync(ViewModel.User.User user, CancellationToken token = default)
{
foreach (UserGameRole userGameRole in user.UserGameRoles)
@@ -53,8 +55,13 @@ internal sealed partial class ProfilePictureService : IProfilePictureService
{
UidProfilePicture profilePicture = UidProfilePicture.From(userGameRole, playerInfo.ProfilePicture);
uidProfilePictureDbService.DeleteUidProfilePictureByUid(userGameRole.GameUid);
uidProfilePictureDbService.UpdateUidProfilePicture(profilePicture);
// We don't use DbTransaction here because it's rather complicated
// to handle transaction over multiple DbContext
lock (syncRoot)
{
uidProfilePictureDbService.DeleteUidProfilePictureByUid(userGameRole.GameUid);
uidProfilePictureDbService.UpdateUidProfilePicture(profilePicture);
}
await TryUpdateUserGameRoleAsync(userGameRole, profilePicture, token).ConfigureAwait(false);
}