Parakoopa
Parakoopa

Reputation: 525

EF Core Includes query

I am attempting to save a User entity to a Room entity in EFCore w/ SQLite. Right after I save the changes I query the database again to get the updated list of users in the room entity. Currently, it returns 0 users, if I stop the code with a break point after it runs this query and look in the database table, I can see the users are associated with the right Room, however I still have 0 results. I am curious if my design or lack there of is the problem? Do I need something that links the user back to the room?

Code that returns 0 users -

public async Task<ServiceResponse<MatchRoom>> RegisterUser(AppState state)
{
    //Update the db with connection ID incase we need it later
    var update = _context.Update(state.user);
    if (update != null)
    {
        //The user object is saved here
        await _context.SaveChangesAsync();
        //Here I query a room, that the user is assigned to, but get nothing.
        var room = _context.MatchRooms.Include("Users");
}

I have the following dbcontext

public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) : base(options)
    {
        //
    }
    
    public DbSet<User> Users { get; set; }
    public DbSet<MatchRoom> MatchRooms { get; set; }
    public DbSet<Message> Messages { get; set; }
    
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MatchRoom>()
            .HasMany<User>(u => u.Users);
            
        modelBuilder.Entity<MatchRoom>()
            .HasMany<Message>(m => m.Messages);
            
        modelBuilder.Entity<Message>()
            .HasOne<User>(r => r.SentBy);
    }    
}

public class MatchRoom
{
    public int MatchRoomId { get; set; }
    public string MatchRoomCode { get; set; }
    [ValidateComplexType]
    public List<User> Users { get; set; } = new List<User>();
    public User CreatedBy { get; set; }
    public List<Message> Messages { get; set; }
}

public class User
{
    public int UserId { get; set; }
    public string UserCode { get; set; }
    [Required(ErrorMessage ="You must specify a username")]
    [StringLength(20,MinimumLength=1,ErrorMessage="Please enter a username no longer than 20 characters")]
    public string Username { get; set; }
    public string ConnectionId { get; set; }
}

public class Message
{
    public int MessageId { get; set; }
    public string Text { get; set; }
    public User SentBy { get; set; }
}

Code db

Upvotes: 0

Views: 38

Answers (1)

atiyar
atiyar

Reputation: 8315

You are only declaring the query, but not executing it.

Change the following line -

var room = _context.MatchRooms.Include("Users");

to -

var room = await _context.MatchRooms.Include(p=> p.Users).ToListAsync();

This will give you a list of all MatchRoom along with their related User lists.

Not sure how you can query a room, that the saved user is assigned to, because I don't see any foreign key property in User class like MatchRoomId that you can use to filter the query. Right now they are being handled by EF generated shadow key, I guess.

Declare a foreign key property in User class -

public int MatchRoomId { get; set; }

Then you can query a single room, that the saved user is assigned to like -

var room = await _context.MatchRooms.Include(p=> p.Users).FirstOrDefaultAsync(p=> p.MatchRoomId == state.user.MatchRoomId)

Upvotes: 1

Related Questions