从视图中引用另一个模型的正确方法是什么?

时间:2013-09-26 01:10:31

标签: asp.net-mvc asp.net-mvc-3 entity-framework

我有两种模式:爬行动物和物种。爬行动物有一个物种,在数据库中存储为ID: enter image description here

我应该如何为Reptile设置详细信息控制器操作/视图,以便它显示Species的Title属性而不是Reptile使用的ID?

我最初的想法只是抓取控制器中的数据并将其传递给ViewBag,但这似乎不合适,而且在设置列表操作时过于复杂。

这样做的正确方法是什么?

似乎我需要创建一个视图模型,但令我困惑的是如何正确设计它以便没有太多的数据库调用。

以下是我对ViewModel的初步尝试:

public class ReptileDetailsModel
{
    [Required]
    public String Species { get; set; }

    //etc...

    public ReptileDetailsModel(Reptile reptile)
    {
        this.Species = reptile.Species.Title;

        // etc...
    }
}

3 个答案:

答案 0 :(得分:1)

以更通用的方式实现相同目标的另一种方法是使用AutoMapper

我能想到的几个优点:

  • 自动映射确切的属性(您只需指定规则例外的任何内容)
  • 集中在一个类/方法中,无论
  • 能够忽略,映射到另一个类属性,甚至是自定义逻辑
  • 非侵入性,由您决定如何/何时使用它。

在您的特定实例中,我会创建一个类似

的映射器
Mapper.CreateMap<Reptile, ReptileDetailsModel>()
    .ForMember(dest => dest.Species, 
        options => options.MapFrom(source => source.Species.Title));

此映射器信息需要在某处注册。在我参与的MVC项目中,我会将一个映射器注册到global.asax。

然后在您的控制器中,您需要调用映射器以将爬行动物实例映射到模型

ReptileDetailsModel model = Mapper.Map<ReptileDetailsModel>(reptile);

在MVC中使用AutoMapper有很多种方法,但这可能是一个开始。

答案 1 :(得分:0)

我当时没有意识到,但我正在使用:

public ActionResult Index()
{
    using (var db = new ModelsContainer())
    {
        return View(db.Reptiles.ToList());
    }
}

这导致数据库(以及模型属性)在呈现视图之前到期,从而导致此错误(为搜索引擎添加):

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

答案 2 :(得分:0)

将Species类设置为强类型爬虫视图的模型。然后显示它的Title属性。您的操作方法应如下所示:

public ActionResult Reptile(Reptile rep)
{
    return View(db.Species.Where(x=>x.ID == rep.SpeciesID).Single());
}

这样你只需要调用一次数据库就可以生成视图。