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

发布于 2025-01-11 07:24:29 字数 2483 浏览 0 评论 0原文

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

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

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

在我的控制器的索引中,我想仅显示当前连接的用户创建的披萨。

这是我的模型:

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 个操作(创建和索引)吗?

I am struggling trying to implement à create action and an index for my controller.

Basically, I want each user to have multiple pizzas.

I want the connected user to create his own pizzas.

And in the index of my controller I want to show, only the pizzas created by the current connected user.

Here are my models :

1/Pizzas :

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/ ApplicationUser :

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

3/ This is my Context :

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);
        }

I want to create a "create action" and an "index action" that shows only the pizzas created by the current connected user. Here is what I have done so far :

1/ Index action method :

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/ Create Action Method :

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

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

Could you please help me with these 2 actions (Create and Index) ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小巷里的女流氓 2025-01-18 07:24:29

根据您的模型和 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 操作方法,我们需要验证模型是否有效,然后根据结果显示验证消息或继续下一步。您可以参考以下教程:

模型ASP.NET Core MVC 和 Razor 页面中的验证

教程:实现 CRUD 功能 - ASP。 NET MVC 与 EF Core

According to your Model and DbContext, I create the actions as below: I'm using the Home Controller and Project name is "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();
        //}
    }

The Index view as below:

@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>

The Create View:

@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>

The result as below:

enter image description here

Generally, in the HttpPost method such as the Create or Update action method, we need to validte the model is valid or not, then based on the result to show validation message or go the next steps. You can refer the following tutorials:

Model validation in ASP.NET Core MVC and Razor Pages

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文