[英]Asp.Net MVC 6 Entity Framework - Model relationships
我最近开始研究Asp.Net MVC(使用MVC 6和Asp 5)。
我试图在2个模型类之间创建一个关系。 产品和类别。 产品属于一个类别,因此一个类别可以包含许多产品。
这是我的模型代码:
public class Category
{
public int id { get; set; }
public string name { get; set; }
public virtual ICollection<Product> product { get; set; }
}
public class Product
{
public int id { get; set; }
public string name { get; set; }
public decimal price { get; set; }
public virtual Category category { get; set; }
}
然后,我使用带有视图的实体框架从模型中创建了2个控制器,然后执行迁移。 然后,我对两者都进行了CRUD操作,但是效果很好,但是问题是我无法将产品分配给类别 。 我只能使用生成的视图来设置产品的名称和价格。
希望有人能帮忙。 显然,我期望某种下拉列表在创建产品时显示所有类别,因此我可以将它们链接在一起。
谢谢。
*编辑* ProductsController-创建方法:
// POST: Products/Create
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Product product)
{
if (ModelState.IsValid)
{
_context.Product.Add(product);
_context.SaveChanges();
return RedirectToAction("Index");
}
return View(product);
}
同样,请注意,我不是在尝试手动添加功能。 我正在尝试使整个脚手架/迁移过程与对象关系一起使用,以便它可以自动为我生成它并加快我的开发过程。
*编辑2 *产品型号更改为:
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public decimal ProductPrice { get; set; }
[ForeignKey("Category")]
public int CategoryID { get; set; }
public virtual Category category { get; set; }
}
现在,当我创建产品时,这将创建一个类别下拉列表。 但是,即使我创建了类别,列表也为空,因此仍然缺少某些内容? 也许类别模型需要其他信息? 这是它在GET创建中显示列表的方式:
// GET: Products/Create
public IActionResult Create()
{
ViewData["CategoryID"] = new SelectList(_context.Category, "id", "category");
return View();
}
这只是一个空列表...快到了,但还没有。
您的产品类别应如下所示
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public decimal ProductPrice { get; set; }
[ForeignKey("Category")]
public int CategoryID {get;set;}
public virtual Category category { get; set; }
}
现在,您的“产品”表中将有一个列,该列将存储该列所属的类别。
要获得包含所有可用类别的下拉列表以启用选择,您可以尝试以下操作
ViewBag.CategoryID= new SelectList(db.Category, "CategoryID", "CategoryName");
在视图中,您可以按以下方式使用它
@Html.DropDownList("CategoryID", null, htmlAttributes: new { @class = "form-control" })
产品需要包含CategoryId(外键)。 然后,您可以告诉EF关系的外观(即使EF 正确地命名也可能会自己弄清楚EF):
public class Category
{
public int CategoryId { get; set; }
public string Name { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
}
public class StoreContext : DbContext
{
public DbSet<Category> Categories{ get; set; }
public DbSet<Product> Products { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// optionally, even EF can follow convention and detect 1-m relationship between product and category.
modelBuilder.Entity<Product>().HasRequired(p => p.Category)
.WithMany(c => c.Products)
.HasForeignKey(p => p.CategoryId);
}
}
创建新产品时,将CategoryId属性设置为正确的值,这会将其连接到类别。
您的ViewModel应该看起来像这样(可以包含整个Product类或以后必须映射的单个属性):
public class ProductViewModel
{
public ProductViewModel()
{
EditableProduct = new Product();
}
public List<SelectListItem> Categories { get; set; }
public Product EditableProduct { get; set; }
}
然后ProductController将填充所有类别并准备视图模型:
public ActionResult Edit(int? id)
{
var model = new ProductViewModel();
model.Categories = dbContext.Categories.Select(x => new SelectListItem() {Text = x.Name, Value = x.Id.ToString()}).ToList();
// check if product even exists
model.EditableProduct = id.HasValue ? dbContext.Products.Find(id.Value) : new Product();
return View(model);
}
[HttpPost, ValidateAntiForgeryToken]
public ActionResult Edit(ProductViewModel model)
{
// check validation
Product product;
if (model.EditableProduct.Id > 0)
product = dbContext.Products.Find(model.EditableProduct.Id);
else
{
product = new Product();
dbContext.Products.Add(product);
}
product.CategoryId = model.EditableProduct.CategoryId;
product.Name = model.EditableProduct.Name;
// add try/catch
dbContext.SaveChanges();
return RedirectToAction("Edit", new {id = product.Id});
}
然后,剃刀视图可以呈现类别:
@Html.DropDownListFor(x => x.EditableProduct.CategoryId, Model.Categories)
这是您可以对所有查找列表和一对多关系遵循的常规模式。
忠告:不要将数据库/域模型“泄漏”到视图中。 将名称,id等属性放入View Model类,并在收到请求并对其进行验证后将它们映射到EF模型。 尽量避免像本例中那样将Product对象放入视图模型中!
这似乎是MVC脚手架中的错误,您可以在此处找到更多详细信息: https : //github.com/aspnet/Scaffolding/issues/149
在您看来,尝试以下操作:
@{ var categories = (IEnumerable<SelectListItem>)ViewData["CategoryID"]; }
<select asp-for="CategoryID" asp-items="categories" class="form-control"></select>
这为我解决了类似的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.