0

I have a model PlayerContext which has one entity of type Inventory (which is a derived type of ItemContainer). These are all within my DbContext called ChunkContext. When I create a new PlayerContext a Inventory is also constructed and both are saved in the database with the correct ID's and everything (I can confirm by looking in the DB). For some reason when I load the PlayerContext later (after it's been saved) the Inventory is not being loaded (it has the default value and ID of 0 which is incorrect). Here is how I'm loading the player (and adding to them to the database if they are a new player):

        using (var db = new ChunkContext())
        {
            PlayerContext playerContext = db.Players
                .Where(p => p.username == username)
                .Include(p => p.inventory)
                .FirstOrDefault();
            // this means the player couldn't be grabbed from the DB
            if (playerContext == null)
            {
                playerContext = new PlayerContext();
                playerContext.username = username;
                db.Players.Add(playerContext);
                db.SaveChanges();
            }
            return new Player(peer, playerContext);
        }

And here is all of the model classes:

class ChunkContext : DbContext
{
    ...
    public DbSet<PlayerContext> Players { get; set; }
    ...
    public DbSet<ItemContainerContext> ItemContainers { get; set; }
    public DbSet<Inventory> Inventories { get; set; }
    ...

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        ...
        modelBuilder.Entity<PlayerContext>().HasOne(p => p.inventory);
        ...
        modelBuilder.Entity<ItemContainerContext>().HasKey(ic => ic.id);
        ...
        base.OnModelCreating(modelBuilder);
    }

_

[Index(nameof(username), IsUnique = true)]
public class PlayerContext
{
    public PlayerContext()
    {
        inventory = new Inventory();
    }
    ...

    [Key]
    public int id { get; set; }
    ...

    [Required]
    public Inventory inventory { get; set; }
    ...
}

_

public class Inventory : ItemContainerContext
{
    ... unrelated gameplay code ...
}

_

public class ItemContainerContext
{
    [Key]
    public int id { get; set; }

    public ItemContainerContext()
    {
        ...
    }

    ...
}
Serge
  • 40,935
  • 4
  • 18
  • 45
Snubber
  • 986
  • 1
  • 10
  • 24
  • when your ```playerContext``` gets null, u are just creating a new ```PlayerContext``` and changin just ```PlayerContext``` informations such as ```username```. It seems like u are not filling enough information to Include ```Inventory```. U better put some red dots while u are debugging and checking out the ```Inventory``` is it null or there is a entity. – BerkGarip May 08 '21 at 20:18
  • 1
    Remove `inventory = new Inventory();` from the `PlayerContext` constructor. You can search SO to find posts explaining why reference navigation properties should *not* be initialized with `new` blank instance. – Ivan Stoev May 09 '21 at 06:18

1 Answers1

1

Try to fix PlayerContext, by removing constructor code and adding a foreign key

public class PlayerContext
{
   
    ...

    [Key]
    public int id { get; set; }
    ...
   
    public int inventoryId { get; set; }

    [ForeignKey(nameof(inventoryId))]
    [InverseProperty("playerContext")]
    public Inventory inventory { get; set; }
    ...
}

public class Inventory : ItemContainerContext
{

[InverseProperty(nameof(PlayerContext.inventory))]
public virtual PlayerContext playerContext{ get; set; }

    ... ...

}

and fix the code

playerContext = new PlayerContext();
playerContext.inventory = new Inventory();
playerContext.username = username;
db.Players.Add(playerContext);
db.SaveChanges();
Serge
  • 40,935
  • 4
  • 18
  • 45