【问题标题】:What is the best way to design a fall back for ObjectContext disposed in .NET MVC为 .NET MVC 中的 ObjectContext 设计回退的最佳方法是什么
【发布时间】:2015-03-05 02:29:47
【问题描述】:

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

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

这样做的问题是,如果我在视图中进行 null 检查,则 ObjectContext 已为 Product.Description 处置,如果它不存在并引发异常。

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

【问题讨论】:

  • 永远不要向视图发送“活动”对象。如果你这样做,你实际上是在混合 UI 和数据层。发送一份副本,其中包含您需要在视图中使用的属性。
  • 将模型映射到视图模型;并在 ViewModel 中使用合理的默认值进行空值检查:public bool HasColor() { Product.Description != null &amp;&amp; Product.Description.Color != null } 具有属性:ProductDescriptionColor {get; set; }

标签: c# asp.net-mvc entity-framework razor


【解决方案1】:

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

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

我知道有些书认为 MVC 中的“M”代表“Domain Model”,他们建议这应该是实例,一个实体框架实体。我不同意,并且觉得这混合了责任。

AutoMapper”工具让我很幸运,它可以轻松地从 EF 实体的属性和您在视图中使用的模型(ViewModel)的属性进行映射。

【讨论】:

  • 你是对的,它不应该。 Automapper 有助于轻松地从这些 ORM 模型对象创建到 DTO 的映射,这些对象有很多悬而未决的事情。
  • 然后将我需要显示的所有内容放在 ViewBag 中是最好的方法吗?
  • @user2865446 不,把它放在 ViewModel 中。 Viewbag 也不是一个好地方。
  • 不,创建一个单独的类(ViewModel),只包含视图中需要的属性。在控制器中,从您的 EF 对象映射到 ViewModel。在视图中使用 ViewModel。
  • @JohnSaunders 您是否有任何资源可用于更多类似 MVC 的最佳实践,也许还有如何设置项目的文件结构等。我的代码从未经过审查,我通常独自开发,所以它容易犯这样的错误。
【解决方案2】:

正如 John 在 cmets 中提到的,以下内容通常不受欢迎:

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>
}

【讨论】:

  • 我认为我已将其编辑为您想要的,但请检查一下。
猜你喜欢
  • 2013-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-02
  • 1970-01-01
  • 2010-12-08
相关资源
最近更新 更多