Search code examples
c#entity-framework-coreasp.net-core-webapi.net-core-3.0

How do process form data and extract properties for two different models/tables using Entity Framework


I have a form on a react-based web game with a form that contains both dungeon and hero data.

After the player fills it out and hits submit, it is sent to my .NetCore 3.1 Entity Framerwork API.

The API needs to save it to 2 different models so that it can be inserted into 2 different database tables.

Those are Dungeon and Heroes.

I have a controller that is supposed to accept the form data and it currently looks like what you see below.

I've figured out how to use one model to update one database table, but how do I do it for two?

Here is my non-working controller code that I've started to write out:

[HttpPost]
public async Task<ActionResult<CreateDungeon>> ProcessForm([FromBody]CreateDungeon data)
{
    // Read quest data from form and add to DB via EF
    _context.Quest.Add(data.Quest);
    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateException)
    {
        if (QuestExists(data.Quest.Id))
        {
            return Conflict();
        }
        else
        {
            throw;
        }
    }

    // Read heroes data from form and add to DB via EF
    _context.Heroes.Add(data.Heroes);
    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateException)
    {
        if (HeroesExists(data.Heroes.Id))
        {
            return Conflict();
        }
        else
        {
            throw;
        }
    }

    return Ok();
}

Is this the correct way of doing this?

Thanks!


Solution

  • To store two different databases in ef-core, you need to create two different dbcontexts.

    First, in the appsettings.json file:

    "ConnectionStrings": {
        "DefaultConnection": "Connection string of the database where the quest table is located",
        "NewConnection": "Connection string of the database where the Heroes table is located"  }
    

    Then, you should have two dbcontexts :

    public class FirstdbContext : DbContext
    {
        public FirstdbContext (DbContextOptions<FirstdbContext > options) : base(options)
        {
        }
        public DbSet<Quest> Quest { get; set; }
    
    }
    
    
    
    public class SeconddbContext : DbContext
    {
        public SeconddbContext (DbContextOptions<SeconddbContext > options) : base(options)
        {
        }
        public DbSet<Heroes> Heroes { get; set; }
    
    }
    

    In startup.cs ConfigureServices method:

     public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddDbContext<FirstdbContext >(options =>
     options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            services.AddDbContext<SeconddbContext >(options =>
     options.UseSqlServer(Configuration.GetConnectionString("NewConnection")));
        }
    

    After the above settings are completed, the controller needs to reference these two dbcontexts.

    [Route("api/[controller]")]
    [ApiController]
    public class HomeController : ControllerBase
    {
        private readonly MydbContext _context1;
        private readonly TestdbContext _context2;
    
        public HomeController (MydbContext context1, TestdbContext context2)
        {
            _context1 = context1;
            _context2 = context2;
        } 
        [HttpPost]
        public async Task<ActionResult<CreateDungeon>> ProcessForm([FromBody]CreateDungeon data)
        {
            // Read quest data from form and add to DB via EF
            _context1.Quest.Add(data.Quest);
            try
            {
                await _context1.SaveChangesAsync();
            }
            catch (DbUpdateException)
            {
                if (QuestExists(data.Quest.Id))
                {
                    return Conflict();
                }
                else
                {
                    throw;
                }
            }
    
            // Read heroes data from form and add to DB via EF
            _context2.Heroes.Add(data.Heroes);
            try
            {
                await _context2.SaveChangesAsync();
            }
            catch (DbUpdateException)
            {
                if (HeroesExists(Heroes.Id))
                {
                    return Conflict();
                }
                else
                { 
                    throw;
                }
            }
    
            return Ok();
        } 
    

    }