外键 属性 设置不正确
Foreign Key property won't set correctly
我用类似的代码制作了一个较早的 post,并更新了模型以使用助手 class 而不是 ViewBag。在更新数据库之前,它似乎很有效。
这些是我的模型 classes.
[Table("Store")]
public class Store
{
[Key]
public int StoreId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
[Table("Purchase")]
public class Purchase
{
[Key]
public int Id { get; set; }
public int StoreId { get; set; }
[ForeignKey("StoreId")]
public Store Store { get; set; }
}
public class PurchaseDBContext : DbContext
{
public DbSet<Purchase> Purchases { get; set; }
public DbSet<Store> Stores { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
public class PurchaseCreateHelper
{
public Purchase Purchase { get; set; }
public List<Store> Stores { get; set; }
}
}
我对这个问题的看法的相关部分:
<div class="form-group">
@Html.LabelFor(model => model.Purchase.StoreId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.Purchase.StoreId, new SelectList(Model.Stores.Select( x => new { StoreId = x.StoreId, DisplayName = x.Name.ToString() + " - " + x.Address.ToString()}), "StoreId", "DisplayName"), new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Purchase.StoreId, "", new { @class = "text-danger" })
</div>
</div>
以及我控制器的相关部分:
// GET: Purchases/Create
public ActionResult Create()
{
var purchaseHelper = new PurchaseCreateHelper()
{
Stores = db.Stores.ToList(),
Purchase = new Purchase()
};
return View(purchaseHelper);
}
// POST: Purchases/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Purchase purchase)
{
if (ModelState.IsValid)
{
db.Purchases.Add(purchase);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(purchase);
}
当我的代码到达 db.Purchases.Add(purchase) 时,购买对象的商店 属性 设置为 null。然而, StoreId 似乎非常好。我不明白为什么 Store 对象不会随着 StoreId 属性 而改变,因为我已经用 [ForeignKey("StoreId")] 对其进行了注释。我哪里弄乱了 StoreId 和 Store 之间的连接?
更新#2
// GET: Purchases
public ActionResult Index()
{
return View(db.Purchases.ToList());
}
@model IEnumerable<BookKeeper.Models.Purchase>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.Store.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Type)
</th>
<th>
@Html.DisplayNameFor(model => model.Price)
</th>
<th>
@Html.DisplayNameFor(model => model.Date)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => (item.Store.Name))
</td>
<td>
@Html.DisplayFor(modelItem => item.Type)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
@Html.DisplayFor(modelItem => item.Date)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
@Html.ActionLink("Details", "Details", new { id = item.Id }) |
@Html.ActionLink("Delete", "Delete", new { id = item.Id })
</td>
</tr>
}
</table>
更新#3
enter image description here
我假设您没有看到 purchase.Store 的任何值,那是因为模型绑定器仅绑定您在 [=13] 中指定的 StoreId(当请求从浏览器发送到 Web 服务器时) =]
@Html.DropDownListFor(model => model.Purchase.StoreId, new SelectList(Model.Stores.Select( x => new { StoreId = x.StoreId, DisplayName = x.Name.ToString() + " - " + x.Address.ToString()}), "StoreId", "DisplayName"), new { @class = "form-control" })
purchase.Store 的填充属于 EF。 EF 将在您这样做时加载该商店
dbContext.Purchases.Include(x => x.Store).FirstOrDefault(x => x.ID == 1234);
更新:
如果您想在 POST 操作中使用 Store 对象
// POST: Purchases/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Purchase purchase)
{
if (ModelState.IsValid)
{
db.Purchases.Add(purchase);
db.SaveChanges();
purchase = dbContext.Purchases.Include(x => x.Store).FirstOrDefault(x => x.ID == purchase.ID); // Not sure why you need Store information at this step.
return RedirectToAction("Index");
}
return View(purchase);
}
我用类似的代码制作了一个较早的 post,并更新了模型以使用助手 class 而不是 ViewBag。在更新数据库之前,它似乎很有效。
这些是我的模型 classes.
[Table("Store")]
public class Store
{
[Key]
public int StoreId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
[Table("Purchase")]
public class Purchase
{
[Key]
public int Id { get; set; }
public int StoreId { get; set; }
[ForeignKey("StoreId")]
public Store Store { get; set; }
}
public class PurchaseDBContext : DbContext
{
public DbSet<Purchase> Purchases { get; set; }
public DbSet<Store> Stores { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
public class PurchaseCreateHelper
{
public Purchase Purchase { get; set; }
public List<Store> Stores { get; set; }
}
}
我对这个问题的看法的相关部分:
<div class="form-group">
@Html.LabelFor(model => model.Purchase.StoreId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.Purchase.StoreId, new SelectList(Model.Stores.Select( x => new { StoreId = x.StoreId, DisplayName = x.Name.ToString() + " - " + x.Address.ToString()}), "StoreId", "DisplayName"), new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Purchase.StoreId, "", new { @class = "text-danger" })
</div>
</div>
以及我控制器的相关部分:
// GET: Purchases/Create
public ActionResult Create()
{
var purchaseHelper = new PurchaseCreateHelper()
{
Stores = db.Stores.ToList(),
Purchase = new Purchase()
};
return View(purchaseHelper);
}
// POST: Purchases/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Purchase purchase)
{
if (ModelState.IsValid)
{
db.Purchases.Add(purchase);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(purchase);
}
当我的代码到达 db.Purchases.Add(purchase) 时,购买对象的商店 属性 设置为 null。然而, StoreId 似乎非常好。我不明白为什么 Store 对象不会随着 StoreId 属性 而改变,因为我已经用 [ForeignKey("StoreId")] 对其进行了注释。我哪里弄乱了 StoreId 和 Store 之间的连接?
更新#2
// GET: Purchases
public ActionResult Index()
{
return View(db.Purchases.ToList());
}
@model IEnumerable<BookKeeper.Models.Purchase>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.Store.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Type)
</th>
<th>
@Html.DisplayNameFor(model => model.Price)
</th>
<th>
@Html.DisplayNameFor(model => model.Date)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => (item.Store.Name))
</td>
<td>
@Html.DisplayFor(modelItem => item.Type)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
@Html.DisplayFor(modelItem => item.Date)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
@Html.ActionLink("Details", "Details", new { id = item.Id }) |
@Html.ActionLink("Delete", "Delete", new { id = item.Id })
</td>
</tr>
}
</table>
更新#3 enter image description here
我假设您没有看到 purchase.Store 的任何值,那是因为模型绑定器仅绑定您在 [=13] 中指定的 StoreId(当请求从浏览器发送到 Web 服务器时) =]
@Html.DropDownListFor(model => model.Purchase.StoreId, new SelectList(Model.Stores.Select( x => new { StoreId = x.StoreId, DisplayName = x.Name.ToString() + " - " + x.Address.ToString()}), "StoreId", "DisplayName"), new { @class = "form-control" })
purchase.Store 的填充属于 EF。 EF 将在您这样做时加载该商店
dbContext.Purchases.Include(x => x.Store).FirstOrDefault(x => x.ID == 1234);
更新:
如果您想在 POST 操作中使用 Store 对象
// POST: Purchases/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Purchase purchase)
{
if (ModelState.IsValid)
{
db.Purchases.Add(purchase);
db.SaveChanges();
purchase = dbContext.Purchases.Include(x => x.Store).FirstOrDefault(x => x.ID == purchase.ID); // Not sure why you need Store information at this step.
return RedirectToAction("Index");
}
return View(purchase);
}