我正在使用实体框架数据库优先方法。我们假设我有一个名为Product
的模型类,该类具有NumberOfViews
属性。在编辑页面中,我将product
类的实例传递给控制器。
问题是我无法在编辑页面中添加@Html.EditorFor(model => model.NumberOfViews)
,因为它假设NumberOfViews
每次访问时都会更新@Html.HiddenFor(model => model.NumberOfViews)
产品页面,网站管理员
我无法将其添加为Product.NumberOfViews = db.Products.Find(Product.Id).NumberOfViews;
,因为如果管理员检查了元素,他可以手动编辑它。
此外,如果我尝试以编程方式在服务器端设置值(例如null
),则会出现以下错误:
ObjectStateManager中已存在具有相同键的对象。 ObjectStateManager无法使用相同的键跟踪多个对象。
如果我不将其添加到视图或控制器中,则值为def __get__(self, instance, owner=None):
,从而覆盖之前的任何值。
那我该怎么办?
答案 0 :(得分:1)
我注意到很多人为他们的实体框架使用与他们的MVC控制器相同的模型。我一般不鼓励这种做法。在我看来,数据库模型与视图模型不同。
有时,视图所需的信息少于数据库模型提供的信息。例如,在修改帐户密码时,视图不需要名字,姓氏或电子邮件地址,即使它们可能都位于同一个表中。
有时它需要来自多个数据库表的信息。例如,如果用户可以为其简档存储无限数量的电话号码,则用户信息将在用户表中,然后联系信息与联系表中的联系信息。但是,在修改用户配置文件时,他们可能希望添加/编辑/删除其中一个或多个数字,因此视图需要所有数字以及名字,姓氏和电子邮件地址。
这就是我要做的事情:
// This is your Entity Framework Model class
[Table("Product")]
public class Product
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ProductId { get; set; }
public string Name { get; set; }
public int NumberOfPageViews { get; set; }
}
// This is the model you will use in your Edit action.
public class EditProductViewModel
{
public int ProductId { get; set; }
public string Name { get; set; }
}
public class ProductController : Controller
{
IProductService service;
//...
[HttpGet]
public ActionResult Edit(int productId)
{
var product = service.GetProduct(productId);
var model = new EditProductViewModel()
{
ProductId = product.ProductId,
Name = product.Name
};
return View(model);
}
[HttpPost]
public ActionResult Edit(EditProductViewModel model)
{
if (ModelState.IsValid)
{
var product = service.GetProduct(model.ProductId);
product.Name = model.Name;
service.Update(product);
}
// ...
}
}