Ядро Entity Framework хранит объект вне контекста БД в памяти

#c# #entity-framework #.net-core #entity-framework-core

#c# #entity-framework #.net-ядро #entity-framework-core

Вопрос:

Я создаю игровой сервер с использованием консольного приложения dotnet core 2.2, у меня есть некоторое недопонимание относительно того, как entity framework работает в некоторых senarios. Я хочу сохранить информацию о пользователе в памяти, но с учетом двух важных факторов.

  1. Я хочу, чтобы данные постоянно обновлялись
  2. Я хочу выполнять минимальное количество запросов к базе данных

Вот как я сейчас это делаю:

DatabaseManager.cs

 internal static class DatabaseManager
{
    public static async Task<User> FindUser(int userId, string token)
    {
        using (var dbContext = new musicContext())
        {
            return await dbContext.User.FirstOrDefaultAsync(u =>
                u.UserId == userId amp;amp; string.Equals(u.Token, token, StringComparison.InvariantCulture));
        }
    }

    public static IEnumerable<Game> GetUserGames(User user)
    {
        using (var dbContext = new musicContext())
        {
            return dbContext.Game
                .Include(g => g.ParticipantOneNavigation)
                .Include(g => g.ParticipantTwoNavigation)
                .Where(g =>
                    g.ParticipantOneNavigation == user || g.ParticipantTwoNavigation == user);
        }
    }
}
  

Player.cs

 internal class Player : IEquatable<Player>
{
    private readonly NetPeer _netPeer;
    private User _user;
    private int _userId;
    private string _token;

    public Player(NetPeer netPeer)
    {
        _netPeer = netPeer;
    }

    public async Task<bool> Authenticate(int userId, string token)
    {
        _user = await DatabaseManager.FindUser(userId, token);

        if (_user is null)
            return false;

        _userId = userId;
        _token = token;

        return true;
    }

    public NetPeer GetPeer()
    {
        return _netPeer;
    }

    public int GetPlayerId()
    {
        FlushData();

        return _user.UserId;
    }

    public string GetUsername()
    {
        FlushData();

        return _user.Username;
    }

    public string GetNickname()
    {
        FlushData();

        return _user.Nickname;
    }

    public string GetPhoneNumber()
    {
        FlushData();

        return _user.PhoneNumber;
    }

    public int GetCoins()
    {
        FlushData();

        return _user.Coins;
    }

    public int GetCups()
    {
        FlushData();

        return _user.Cups;
    }

    public bool IsAuthenticated()
    {
        return _user != null;
    }

    public bool IsSuspended(out DateTimeOffset suspendedUntil)
    {
        suspendedUntil = _user.SuspendedUntil.GetValueOrDefault();

        return _user.Suspended;
    }

    public bool Equals(Player other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return _playerId == other._playerId;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        return obj.GetType() == GetType() amp;amp; Equals((Player)obj);
    }

    public override int GetHashCode()
    {
        return _playerId;
    }

    private async void FlushData()
    {
        _user = await DatabaseManager.FindUser(_userId, _token);
    }
}
  

Является ли это оптимальным способом сделать это? Если нет, что вы можете предложить, чтобы сделать это лучше?

Ответ №1:

Вы не можете этого сделать, потому что база данных предназначена для сохранения данных, а частые запросы неизбежны для постоянного обновления данных.

Если вам нужно средство обмена информацией в режиме реального времени, вам необходимо разработать и запустить серверное приложение с двусторонней связью (например. UDP, TCP, WebSocket. А что касается .NET Core, ASP.NET Рекомендуется использовать Core SignalR.), который мог бы кэшировать, уведомлять и отправлять обновления данных клиентам. Чтобы сохранить данные, вы могли бы периодически обновлять базу данных из кэша через серверное приложение. Это также может улучшить целостность и безопасность бизнес-данных.