如何使用实体框架保存带有外键的新记录
本文关键字:新记录 何使用 实体 框架 保存 | 更新日期: 2023-09-27 18:35:23
所以我有两个模型,产品和评论。产品模型包含一个名为"审阅"的导航属性,如下所示:
Public class Product
{
[HiddenInput(DisplayValue=False])
public int ProductID {get; set;}
[Required]
public string ProductName {get; set;}
[HiddenInput(DisplayValue=False)
public ICollection<Reviews> {get; set;}
}
审查模型:
public class Review
{
[HiddenInput(DisplayValue=false)]
public int ReviewId { get; set; }
[Required]
public int ProductID { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Subject { get; set; }
[Required]
public string Body { get; set; }
}
我有一个Action
ViewResult
方法,用于产品详细信息,它可以获取所有产品以及具有相同FK
产品ID的所有评论,如下所示:
public ViewResult ProductDetails(int productId)
{
Product product = repository.Products
.Include(p => p.Reviews)
.FirstOrDefault(p => p.ProductID == productId);
return View(product);
}
然后有一个包含非常简单的HTML元素的View
,您可以在下面看到它:
@model app.models.Product
@Html.DisplayFor(model => model.ProductName)
@foreach (var review in Model.Reviews)
{
@Html.Partial("_Reviews", review)
}
在上面的视图中,我要求使用部分视图来呈现所有评论都属于该特定产品。在"部分"视图中,我有一个表单,用户可以在其中提交评论。我希望用户提交名称位于视图顶部的产品的评论。我知道我必须为此创建一个操作,但唯一让我感到不舒服的是我无法弄清楚如何获得该特定产品的ProductID
。
编辑:根据斯蒂芬的回答,我不得不将表单 Html 元素放入主视图中,即 ProducDetails,并放置了一些脚本来调用 Json 结果以将数据保存在数据库中。
保存审阅的控制器方法:
[HttpPost]
public JsonResult CreateReview (Review review)
{
if (review.ReviewId == 0)
{
db.Reviews.Add(review);
}
else
{
Review dbEntry = db.Reviews.Find(review.ReviewId);
if (dbEntry != null)
{
dbEntry.ProductID = review.ProductID;
dbEntry.Name = review.Name;
dbEntry.Subject = review.Subject;
dbEntry.Body = review.Body;
}
}
db.SaveChanges();
return Json(true);
}
您希望
为Product
创建一个新Review
,因此窗体需要位于主视图中,而不是部分视图中。以下假设您希望使用 ajax 提交并更新现有评论的列表
@model app.models.Product
@Html.DisplayFor(model => model.ProductName)
// display existing reviews
<div id="reviews">
@foreach (var review in Model.Reviews)
{
@Html.DisplayFor(m => review.Body)
}
</div>
<h2>Create new Review</h2>
@Html.Partial("_NewReview", new Review(){ ProductID = Model.ProductID })
_NewReview.cshtml
在哪里
@model Review
@using (Html.BeginForm())
{
@Html.HiddenFor(m => m.ProductID)
@Html.EditorFor(m => m.Name)
@Html.EditorFor(m => m.Subject)
@Html.TextAreaFor(m => m.Body)
<input id="create" type="submit" value="Create" />
}
并删除_Reviews.cshtml
文件
然后在主视图中,添加以下脚本
var url = '@Url.Action("Create", "Review")';
var reviews = $('#reviews');
var form = $('form');
$('#create').click(function() {
$.post(url, form.serialize(), function(response) {
if (response) {
reviews.append($('#Body').val()); // add the new Review to the existing reviews
form.get(0).reset(); // reset the form controls
}
}).fail(function (result) {
// oops
});
return false; // cancel the default submit
});
将提交给(ReviewController
)
[HttpPost]
public JsonResult Create(Review model)
{
// Save the model
return Json(true); // return something to indicate success
}
正如我所能想象的那样,ProductId 是唯一的在分部视图中,您可以在 Ajax.BeginForm 中编写代码
@model Review
@Ajax.BeginForm("ActionName", "ControllerName", new { productId = Model.ProductId }, @*AjaxOptions Attribute*@)
{
Review Fields here
<input type="submit" value="Submit Review"/>
}
要获得ProductID
,您必须在Review Table
中添加Product Table
的ForeignKey
。
public class Review
{
[HiddenInput(DisplayValue=false)]
public int ReviewId { get; set; }
[Required]
public int ProductID { get; set; }
[Required]
[ForeignKey("ProductID")]
publiv virtual Product {get;set;}
}
希望这有帮助