为 .NET MVC 中的 ObjectContext 设计回退的最佳方法是什么

What is the best way to design a fall back for ObjectContext disposed in .NET MVC

我正在尝试在我的视图中显示对象的 属性(如果存在),否则回退到默认值,例如

@if(Product.Description != null && Product.Description.Color != null){
    <li>@Product.Description.Color</li>
}

这个问题是,如果我在视图中进行 null 检查,ObjectContext 已被释放 Product.Description 如果它不存在并抛出异常。

我应该在我的控制器中分配一个默认值/回退,还是有办法在视图中处理这个问题?

永远不要向视图发送 "live" 对象。如果这样做,您实际上是在混合 UI 和数据层。请记住,在呈现视图时控制器已完成执行。

而是发送一份副本,其中包含您需要在视图中使用的属性。

我知道有些书建议 MVC 中的 "M" 代表 "Domain Model" 他们建议这应该是一个Entity Framework 实体的实例。我不同意,并认为混合责任。

我很幸运地使用了“AutoMapper”工具,它使从 EF 实体的属性和您在视图(ViewModel)中使用的模型的属性映射变得简单。

正如约翰在评论中提到的,以下内容通常是不受欢迎的:

public ActionResult Index()
{
  var db = new MyDbContext();

  var model = db.Products.FirstOrDefault();

  return View(model);
}

相反,在将值映射到视图模型时正确处理上下文:

public ActionResult Index()
{
  var model = new IndexVM();

  using (var db = new MyDbContext())
  {
    // Assuming EF
    var dbProduct = db.Products.FirstOrDefault();
    // Even better performance:
    var dbProduct = db.Products
      // prevent lazy loading
      .Include(p => p.Description.Color)
      .FirstOrDefault()
      // prevent ef tracking with proxy objects
      .AsNoTracking();

    // can be automated with AutoMapper or other .Net Components
    ProductVM productVM = new ProductVM();
    productVM.Id = dbProduct.Id;
    // etc

    // Don't put logic in View:
    productVM.HasDescription = (product.Description != null);
    if (productVM.HasDescription)
    {
       var descriptionVM = new DescriptionVM();
       // map values
       productVM.Description = descriptionVM;
    }

    model.Product = productVM;
  }

  return View(model);
}

现在视图本身并没有真正执行逻辑:

@if(product.HasDescription && product.Description.HasColor){
  <li>@Product.Description.Color</li>
}