Entity Framework Core, one-to-many relationship, collection always empty

.net-core asp.net-web-api c# entity-framework-core

Question

I'm trying to do a simple one to many relationship in a InMemory database that is built up in runtime by http requests. I'm new to Entity Framework Core, so I'm unsure if the is a proper way of working with it.

ValuesController.cs

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    private readonly DataListContext _Context;
    public ValuesController(DataListContext context)
    {
        _Context = context;
    }

    [HttpGet]
    public ActionResult<IEnumerable<DataList>> Get()
    { 
        // Datas keeps is value
        Console.WriteLine("Root Count: " + _Context.RootDatas.Count());
        if (_Context.RootDataLists.Count() > 0)
        {
            // InsideDatas is always 
            Console.WriteLine("Inside Count: " + _Context.RootDataLists.First().InsideDatas.Count);empty next request
        }

        return _Context.RootDataLists.ToList();
    }

    [HttpPost]
    public void Post([FromBody] string value)
    {
        var data = new Data() { Id = Guid.NewGuid() };
        _Context.RootDatas.Add(data);

        var dataList = new DataList();
        dataList.Name = value;
        dataList.InsideDatas.Add(data);

        _Context.RootDataLists.Add(dataList);
        _Context.SaveChanges();

        // InsideDatas has an element
        Console.WriteLine("Inside Count: " + _Context.RootDataLists.First().InsideDatas.Count);
    }
}

public class DataListContext : DbContext
{
    public DbSet<DataList> RootDataLists { get; set; }
    public DbSet<Data> RootDatas { get; set; }
    public DataListContext(DbContextOptions<DataListContext> options) : base(options) { }
}

public class Data
{
    [Key] public Guid Id { get; set; }
}

public class DataList
{
    public DataList()
    {
        InsideDatas = new List<Data>();
    }

    [Key]
    public string Name { get; set; }
    public ICollection<Data> InsideDatas { get; set; }
}

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<DataListContext>(options => options.UseInMemoryDatabase(databaseName: "DataList"));
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMvc();
    }
}

My problem if that the InsideDatas list is always empty in the next call, but not RootDatas. The DbSet RootDatas in DataListContext is not really anything I would need in my application, but I though it would make the database keep the InsideDatas element. But no.

So I'm I using this all wrong? My use case is a server listing, built up in runtime by hosts posting it's presence to the listing service. My plan is to swap the InMemoryDatabase for redis to be able to scale this properly if needed. (This code is just a slimmed version of the actual one with he same problem)

1
0
6/30/2019 1:59:21 PM

Accepted Answer

You need to tell EF Core to load related entities. One way is through eager loading:

// notice the Include statement
_Context.RootDataLists.Include(x => x.InsideDatas).First().InsideDatas
1
6/30/2019 3:49:11 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow