add reorderable collection

This commit is contained in:
Lightczx
2023-09-04 17:15:34 +08:00
committed by DismissedLight
parent 14f1b43e08
commit b8a7ecdd40
2 changed files with 75 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
namespace Snap.Hutao.Core.Database;
internal interface IReorderable
{
int Index { get; set; }
}

View File

@@ -0,0 +1,66 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Microsoft.EntityFrameworkCore;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Runtime.InteropServices;
namespace Snap.Hutao.Core.Database;
internal sealed class ObservableReorderableDbCollection<T> : ObservableCollection<T>
where T : class, IReorderable
{
private readonly DbContext dbContext;
private bool previousChangeIsRemoved;
public ObservableReorderableDbCollection(List<T> items, DbContext dbContext)
: base(AdjustIndex(items))
{
this.dbContext = dbContext;
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
base.OnCollectionChanged(e);
switch (e.Action)
{
case NotifyCollectionChangedAction.Remove:
previousChangeIsRemoved = true;
break;
case NotifyCollectionChangedAction.Add:
if (!previousChangeIsRemoved)
{
return;
}
OnReorder();
previousChangeIsRemoved = false;
break;
}
}
private static List<T> AdjustIndex(List<T> list)
{
Span<T> span = CollectionsMarshal.AsSpan(list);
for (int i = 0; i < list.Count; i++)
{
ref readonly T item = ref span[i];
item.Index = i;
}
return list;
}
private void OnReorder()
{
AdjustIndex((List<T>)Items);
DbSet<T> dbSet = dbContext.Set<T>();
foreach (ref readonly T item in CollectionsMarshal.AsSpan((List<T>)Items))
{
dbSet.UpdateAndSave(item);
}
}
}