Home > database >  Foreign key is NULL in ASP.NET in 1 to many relationship. How do I add it in controller?
Foreign key is NULL in ASP.NET in 1 to many relationship. How do I add it in controller?

Time:10-27

I'm trying to create a 1 to many relationship between my recipe table and AspNet user table, but I end up with NULL as my foreign key whenever I create a new recipe. public virtual ApplicationUser ApplicationUser { get; set; } is in my Recipe model and public List<Recipe> Recipes { get; set; } is in my ApplicationUser model

Recipes table after i've added some test recipes in DbInitializer. Row 3 was created through localhost and the foreign key is NULL.

  foreach (var u in db.Users.Include(b => b.Recipes) )
        {
            for (int i = 1; i < 3; i  )
            {
                u.Recipes.Add(new Recipe
                {
                    Title = $"{i}",
                    Introduction =  $"{i}",
                    Ingredients =  $"{i}",
                    Instructions =  $"{i}", 
                    Nutrients =  $"{i}"
                    
                });
            }
        }
        db.SaveChanges();

I just can't figure out how to set the foreign key in the Controller for when I create a new recipe :

        [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create([Bind("Id,Title,Introduction,Ingredients,Instructions,Nutrients")] Recipe recipe)
    {
        if (ModelState.IsValid)
        {
            _context.Add(recipe);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        return View(recipe);
    }

Sorry if my post is messy, this is the first time I've posted here.

EDIT: I'm uncertain but is this what you asked for? I would access user id by just typing in user.Id right?

   public class RecipesController : Controller
{
    private readonly ApplicationDbContext _context;
    private readonly UserManager<ApplicationUser> _userManager;

    public RecipesController(ApplicationDbContext context, UserManager<ApplicationUser> userManager)
    {
        _context = context;
        _userManager = userManager;
    }

EDIT 2: Thanks for the help, the code correctly assigned a foreign key now.

        public async Task<IActionResult> Create([Bind("Id,Title,Introduction,Ingredients,Instructions,Nutrients")] Recipe recipe)
    {
        if (ModelState.IsValid)
        {
            // Adding the foreign key to recipes
            var user = await _userManager.GetUserAsync(User);
            recipe.UserId = user.Id;
            
            _context.Add(recipe);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        return View(recipe);
    }

CodePudding user response:

There are a number of ways to do this, I personally assign audit info inside the DbContext.SaveChanges() method, but that's a global approach that's out of scope for this post.

At a fundamental level you need to assign the user before you call SaveChanges() so the following code might work in your case:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Title,Introduction,Ingredients,Instructions,Nutrients")] Recipe recipe)
{
    if (ModelState.IsValid)
    {
        // assign the user
        var user = await _userManager.GetUserAsync(User);
        recipe.ApplicationUser = user;

        _context.Add(recipe);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(recipe);
}

NOTE: This is just a guide, in some cases the above assignment may not work, especially if your UserManager does not use the save DbContext instance. In such a case you will find it simpler to assign the user using the Foreign Key, not the navigation property.

  • Related