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
我正在努力尝试为我的控制器实现 à 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