Merge pull request #840 from nolt/fix-admin-panel-account-search
Search accounts in the database instead of loading all of them (cherry picked from commit 4e806cbe64f855a765e864c0c2ff45238f487e36)
This commit is contained in:
@@ -100,6 +100,26 @@ internal class PlayerContext : CachingEntityFrameworkContext, IPlayerContext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async ValueTask<IEnumerable<DataModel.Entities.Account>> SearchAccountsAsync(string searchTerm, int skip, int count, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
using (this.RepositoryProvider.ContextStack.UseContext(this))
|
||||||
|
{
|
||||||
|
// Invariant: this one runs in .NET, so it must not depend on the server's locale - in a
|
||||||
|
// Turkish one, "I".ToLower() is a dotless "ı" and the term would match nothing. The
|
||||||
|
// ToLower() calls inside the query below are a different matter: they are translated to
|
||||||
|
// the database's own lower(), which is why they cannot take a culture.
|
||||||
|
var term = searchTerm.ToLowerInvariant();
|
||||||
|
return await this.Context.Set<Account>().AsNoTracking()
|
||||||
|
.Where(a => a.LoginName.ToLower().Contains(term)
|
||||||
|
|| a.RawCharacters.Any(c => c.Name.ToLower().Contains(term)))
|
||||||
|
.OrderBy(a => a.LoginName)
|
||||||
|
.Skip(skip)
|
||||||
|
.Take(count)
|
||||||
|
.ToListAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async ValueTask<DataModel.Entities.Account?> GetAccountByCharacterNameAsync(string characterName, CancellationToken cancellationToken = default)
|
public async ValueTask<DataModel.Entities.Account?> GetAccountByCharacterNameAsync(string characterName, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -78,6 +78,19 @@ public interface IPlayerContext : IContext
|
|||||||
/// </returns>
|
/// </returns>
|
||||||
ValueTask<IEnumerable<Account>> GetAccountsOrderedByLoginNameAsync(int skip, int count, CancellationToken cancellationToken = default);
|
ValueTask<IEnumerable<Account>> GetAccountsOrderedByLoginNameAsync(int skip, int count, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the accounts which contain the search term in their login name or in one of
|
||||||
|
/// their character names, ordered by login name.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="searchTerm">The search term.</param>
|
||||||
|
/// <param name="skip">The skip count.</param>
|
||||||
|
/// <param name="count">The count.</param>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// The account objects, without dependent data.
|
||||||
|
/// </returns>
|
||||||
|
ValueTask<IEnumerable<Account>> SearchAccountsAsync(string searchTerm, int skip, int count, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the account by character name.
|
/// Gets the account by character name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -57,6 +57,18 @@ public class PlayerInMemoryContext : InMemoryContext, IPlayerContext
|
|||||||
return allAccounts.OrderBy(a => a.LoginName).Skip(skip).Take(count);
|
return allAccounts.OrderBy(a => a.LoginName).Skip(skip).Take(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public async ValueTask<IEnumerable<MUnique.OpenMU.DataModel.Entities.Account>> SearchAccountsAsync(string searchTerm, int skip, int count, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var allAccounts = await this.Provider.GetRepository<Account>().GetAllAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
return allAccounts
|
||||||
|
.Where(a => a.LoginName.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)
|
||||||
|
|| a.Characters.Any(c => c.Name.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)))
|
||||||
|
.OrderBy(a => a.LoginName)
|
||||||
|
.Skip(skip)
|
||||||
|
.Take(count);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async ValueTask<bool> CanSaveLetterAsync(Interfaces.LetterHeader letterHeader, CancellationToken cancellationToken = default)
|
public async ValueTask<bool> CanSaveLetterAsync(Interfaces.LetterHeader letterHeader, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -80,18 +80,14 @@ public class AccountService : IDataService<Account>, ISupportDataChangedNotifica
|
|||||||
return (await playerContext.GetAccountsOrderedByLoginNameAsync(offset, count).ConfigureAwait(false)).ToList();
|
return (await playerContext.GetAccountsOrderedByLoginNameAsync(offset, count).ConfigureAwait(false)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
var allAccounts = await playerContext.GetAsync<Account>().ConfigureAwait(false);
|
var results = (await playerContext.SearchAccountsAsync(filter, offset, count).ConfigureAwait(false)).ToList();
|
||||||
var results = allAccounts.Where(account =>
|
if (results.Count == 0 && offset > 0)
|
||||||
(account.LoginName != null && account.LoginName.Contains(filter, StringComparison.InvariantCultureIgnoreCase))
|
|
||||||
|| account.Characters.Any(c => c.Name != null && c.Name.Contains(filter, StringComparison.InvariantCultureIgnoreCase))
|
|
||||||
).ToList();
|
|
||||||
|
|
||||||
if (offset >= results.Count)
|
|
||||||
{
|
{
|
||||||
return results.Take(count).ToList();
|
// The filter narrowed the result set down to less entries than the current page offset - show the first page instead.
|
||||||
|
results = (await playerContext.SearchAccountsAsync(filter, 0, count).ConfigureAwait(false)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
return results.Skip(offset).Take(count).ToList();
|
return results;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user