简体   繁体   中英

Entity Framework Core store an entity outside of db context in memory

I'm creating a game server using dotnet core 2.2 console application, I have some misunderstanding about how entity framework works in certain senarios. I want to store a user information in memory but with 2 important factors in mind.

  1. I want the data to be up to date all the time
  2. I want to do minimum amount of queries to the database

Here's the way I'm currently doing it:

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 && 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() && Equals((Player)obj);
    }

    public override int GetHashCode()
    {
        return _playerId;
    }

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

Is this an optimal way of doing it ? If no what can you suggest to make it better ?

You cannot do this because the database is for data persistence, and frequent queries are inavoidable to keep the data up to date all the time.

If you need a real-time information exchanging facility, you need to develop and run a server-side application with duplex communication (eg. UDP, TCP, WebSocket. And as for .NET Core, ASP.NET Core SignalR is recommanded.), which could cache, notify and push the data updates to the clients. In order to persist the data, you could update the database periodly from the cache via the server-side application. This may also benefit the integrity and security of the business data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM