【问题标题】:LinqToSql MVC3 UpdateLinqToSql MVC3 更新
【发布时间】:2011-04-18 17:38:09
【问题描述】:

我使用 ASP.NET MVC3 作为数据层 LinqToSql。 我有点困惑如何编辑实体。

public ActionResult Edit(int id)
{
    var product = _repository.GetById(id);
    return View(product);
}


[HttpPost]
public ActionResult Edit(Product product)
{
    if (ModelState.IsValid)
    {
        _repository.EditProduct(product);
        return RedirectToAction("Index");
    }
    return View();
}

Edit() 中的变量乘积是可以的,但是在编辑视图之后在 [HttpPost] Edit 中传入的变量 在链接属性中有 null 并且似乎与我的 DataContext 分离。 还有我应该在 EditProduct 方法中执行什么代码来更新实体?

谢谢。

【问题讨论】:

    标签: asp.net-mvc linq-to-sql asp.net-mvc-3 datacontext


    【解决方案1】:

    我假设您的存储库中有一个数据上下文对象。在您的 EditProduct 调用中,您应该有类似的内容:

    Product prod = dataContext.Products.Single(p=>p.ProductID == product.ProductID);
    
    prod.PropertyA = product.PropertyA;
    prod.PropertyB = product.PropertyB;
    dataContext.SubmitChanges();
    

    您还可以附加进来的产品并保存(如果您有时间戳列):

    dataContext.Products.Attach(product,true);
    dataContext.SubmitChanges();
    

    如果你没有时间戳列,那么 L2S 将抛出一个关于无法检查其状态的错误。

    如果实体声明了版本成员或没有更新检查策略,则只能在没有原始状态的情况下附加已修改的实体。

    如果您向数据库添加时间戳列,则 L2S 可以执行上述操作。

    Here's a deeper explanation.

    【讨论】:

    • 很好的答案,但在这里使用 .First 方法是错误的。这将忽略多个实体与查询匹配的情况。通常,您的主键会阻止这种情况发生,但您不想让自己对它敞开心扉。请改用 Single 或 SingleOrDefault。
    • 我应该遍历所有属性吗?
    • 更新了帖子以纠正我的“.First”错误并添加了附加产品的方法。
    • @Vladimir,通过您必须使用反射的属性“迭代”。另一种方法是使用 AutoMapper:automapper.codeplex.com
    • @Milimetric 如果我的实体相对较小(5 个属性),可以逐个属性地克隆它吗?
    【解决方案2】:
    public void EditProduct(Product product) {
        using (var context = new MyContext()) {
            var dbProduct = context.Product.Single(r => r.Id == product.Id);
            dbProduct.Property = product.Property;
            dbProduct.ProductCategory = context.ProductCategory.Single(r => r.Id == product.ProductCategoryId);
            context.SubmitChanges();
        }
    }
    
    1. 您的 Edit(Product product) 方法将从 HTTP 请求参数创建一个 Product 实例。它使用反射并查看 Product 类的属性以查看与 HTTP 请求匹配的内容。这称为模型绑定,您可以进一步研究它以了解它是如何工作的。您的产品实例没有链接并且与您的上下文分离的原因是因为它是作为一个新的普通对象创建的。
    2. 您的 EditProduct 代码可能与上述类似。

    (留给读者练习,让上面的代码处理异常、验证等)

    【讨论】:

    • @Vladimir-nani 编辑的链接属性为空是什么意思?你的意思是你有一个编辑超链接,你试图将一个值传递给它并且它是空的?
    • @Vladimir 和@klabranche:不,我相信@Vladimir 正在谈论编辑两个表之间的关系(例如 Product 和 ProductCategory)。所以,为了展示一个例子,我编辑了上面的代码。
    【解决方案3】:

    我找到了最适合我需要的方法

    public ActionResult Edit(int id)
    {
        ViewBag.Categories = _repository.GetAllCategories();
        var product = _repository.GetById(id);
        return View(product);
    }
    
    
    [HttpPost]
    public ActionResult Edit(int id, FormCollection collection) {
        var product = _repository.GetById(id);
        if (TryUpdateModel(product)) {
            _repository.Commit();
            return RedirectToAction("Index");
        }
        ViewBag.Categories = _repository.GetAllCategories();
        return View(product);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多