ApplicationUser 和其他对象之间的一对多关系

One-To-Many relationship between ApplicationUser and an other object

我正在努力尝试为我的控制器实现 à create 操作和索引。

基本上,我希望每个用户都有多个披萨。

我希望连接的用户创建自己的比萨饼。

在我的控制器的索引中,我想显示的只有当前连接的用户创建的比萨饼。

这是我的模型:

1/披萨:

public class PizzaModel
    {
        [Key]
        public int PizzaID { get; set; }

        [Display(Name = "Nom")]
        public string nom { get; set; }
        [Display(Name = "Prix(€)")]
        public float prix { get; set; }
        [Display(Name = "Végétarienne")]
        public bool vegetarienne { get; set; }
        [Display(Name = "Ingrédients")]
        public string ingredients { get; set; }

       
       
        public virtual ApplicationUser ApplicationUser { get; set; }

        
        public string ApplicationUserId { get; set; }

    }

2/ 应用程序用户:

public class ApplicationUser : IdentityUser
    {
        public ICollection<PizzaModel> Pizzas { get; set; }
    }

3/ 这是我的背景:

public class AuthDbContext : IdentityDbContext<ApplicationUser>
    {
        public AuthDbContext(DbContextOptions<AuthDbContext> options) : base(options)
        {

        }

        public DbSet<PizzaModel> Pizzas { get; set; }

        public DbSet<ApplicationUser> ApplicationUsers { get; set; }    

        protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.Entity<ApplicationUser>()
                .HasMany(p => p.Pizzas)
                .WithOne(u => u.ApplicationUser)
                .IsRequired()
                .HasForeignKey(p => p.ApplicationUserId);

            base.OnModelCreating(builder);
        }

我想创建一个“创建操作”和一个“索引操作”,仅显示当前连接的用户创建的比萨饼。这是我到目前为止所做的:

1/索引操作方法:

public async Task<IActionResult> Index(string searchByName)
        {

            var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);

            IEnumerable<PizzaModel> pizzas = new List<PizzaModel>();
            
            pizzas = _context.Pizzas.Where(x => x.ApplicationUserId == userId);
            

            return View(pizzas);
        }

2/ 创建操作方法:

public async Task<IActionResult> Create(PizzaModel model)
        {

                _context.ApplicationUsers.Add(model);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index), "Pizza");
                
        }

你能帮我完成这 2 个操作(创建和索引)吗?

根据您的模型和 DbContext,我创建了如下操作:我使用的是家庭控制器,项目名称是“WebApplication3”

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    private readonly ApplicationDbContext _dbContext;

    public HomeController(ILogger<HomeController> logger, ApplicationDbContext dbContext)
    {
        _logger = logger;
        _dbContext = dbContext;
    }

    public IActionResult Index()
    {
        var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
        
        IEnumerable<PizzaModel> pizzas = new List<PizzaModel>();

        pizzas = _dbContext.Pizzas.Where(x => x.ApplicationUserId == userId);
         
        return View(pizzas);
    }


    public IActionResult Create()
    {
        return View();
    }

    [HttpPost]
    public async Task<IActionResult> Create(PizzaModel model)
    {
        //Note: if you check the ModelState.IsValid, it will return false, because there is no ApplicationID and PizzaID,
        //you can create a view model to enter the new value, then, convert it to PizzaModel
        //validate the model
        //if (ModelState.IsValid)
        //{
        //get current user id
        var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);

            if (userId != null)
            {
                //based on the userid to find current user and get its pizzas.
                var currentuser = _dbContext.ApplicationUsers.Include(c => c.Pizzas).First(c => c.Id == userId);
                List<PizzaModel> pizzas = new List<PizzaModel>();
                pizzas = currentuser.Pizzas.ToList();

                //add the new item to pizza list
                pizzas.Add(new PizzaModel()
                {
                    nom = model.nom,
                    prix = model.prix,
                    vegetarienne = model.vegetarienne,
                    ingredients = model.ingredients
                });
                //update the pizzas for current user.
                currentuser.Pizzas = pizzas;
                await _dbContext.SaveChangesAsync();
            }

            return RedirectToAction(nameof(Index));
        //}
        //else
        //{
        //    return View();
        //}
    }

索引视图如下:

@model IEnumerable<WebApplication3.Data.PizzaModel>

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>


<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.PizzaID)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.nom)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.prix)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.vegetarienne)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ingredients)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ApplicationUserId)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @if(Model.ToList().Count > 0)
        {
            @foreach (var item in Model) {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.PizzaID)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.nom)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.prix)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.vegetarienne)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.ingredients)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.ApplicationUserId)
                    </td>
                    <td>
                        @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
                        @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
                        @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
                    </td>
                </tr>
            }
        }
        else
        {
            <tr><td colspan="7">Empty</td></tr>
        }

    </tbody>
</table>

<p>
    <a asp-action="Create">Create New Pizza</a>
</p>

创建视图:

@model WebApplication3.Data.PizzaModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>PizzaModel</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div> 
            <div class="form-group">
                <label asp-for="nom" class="control-label"></label>
                <input asp-for="nom" class="form-control" />
                <span asp-validation-for="nom" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="prix" class="control-label"></label>
                <input asp-for="prix" class="form-control" />
                <span asp-validation-for="prix" class="text-danger"></span>
            </div>
            <div class="form-group form-check">
                <label class="form-check-label">
                    <input class="form-check-input" asp-for="vegetarienne" /> @Html.DisplayNameFor(model => model.vegetarienne)
                </label>
            </div>
            <div class="form-group">
                <label asp-for="ingredients" class="control-label"></label>
                <input asp-for="ingredients" class="form-control" />
                <span asp-validation-for="ingredients" class="text-danger"></span>
            </div> 
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

结果如下:

一般来说,在HttpPost方法中,比如Create或Update action方法,我们需要验证模型是否有效,然后根据结果显示验证消息或进行下一步。您可以参考以下教程:

Model validation in ASP.NET Core MVC and Razor Pages

Tutorial: Implement CRUD Functionality - ASP.NET MVC with EF Core