【问题标题】:Using two models in one controller?在一个控制器中使用两个模型?
【发布时间】:2013-05-24 18:58:19
【问题描述】:

我目前有一个带有主页的应用程序,它根据“创建”或输入数据库的日期显示十部电影的列表。我还想根据每部电影的评分显示前十部电影的列表。有没有办法传入另一个模型或改变我当前的 ViewModel 来做到这一点?这是我的家庭控制器的索引部分:

    public ActionResult Index()
    {
        var model =
            _db.Movies
                .OrderByDescending(m => m.DateEntered)
                .Take(10)
                .Select(m => new MovieListViewModel 
                {
                    Id = m.Id,
                    Title = m.Title,
                    Genre = m.Genre,
                    ReleaseDate =  m.ReleaseDate,
                    CountOfReviews = m.Reviews.Count()
                });

        return View(model);

    }

以及传入的 ViewModel:

public class MovieListViewModel
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Genre { get; set; }

    [Display(Name="Year Released")]
    public DateTime ReleaseDate { get; set; }
    public int CountOfReviews { get; set; }
}

【问题讨论】:

  • 您可以组合包含两个结果集的单个视图模型。这在读/写场景中变得有点棘手,但对于显示信息来说非常简单。

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


【解决方案1】:

创建一个包含两个列表的模型:

public class MovieListViewModel
{
  public List<MovieModel> Top10ByCreated { get; set; }
  public List<MovieModel> Top10ByRating { get; set; }
}

public class MovieModel
{
  public int Id { get; set; }
  public string Title { get; set; }
  public string Genre { get; set; }

  [Display(Name="Year Released")]
  public DateTime ReleaseDate { get; set; }
  public int CountOfReviews { get; set; }
}

然后在你的控制器中:

var model = new MovieListViewModel();

model.Top10ByCreated = ...
model.Top10ByRating = ...

return View(model);

在您看来,使用MovieListViewModel 作为您的模型,并根据需要使用您的两个列表。

【讨论】:

  • 我喜欢。非常直接和简单。我要去试一试。 :)
【解决方案2】:

只需创建另一个视图模型,两个列表具有两个属性:

public class MovieIndexViewModel
{
    public IEnumerable<MovieListViewModel> TopTenByDate { get; set; }
    public IEnumerable<MovieListViewModel> TopTenByRating { get; set; }
}

在控制器中,您可以创建此视图模型并传递两个列表:

public ActionResult Index()
    {
        var vm = new MovieIndexViewModel();

        vm.TopTenByDate = ....;
        vm.TomTenByRating = ...;

        return View(vm );

    }

【讨论】:

    【解决方案3】:

    您可以组合包含两个结果集的单个视图模型。然后控制器实例化父类型并根据您的需要填充子集合。

    public sealed class HomeViewModel{
        public MovieListViewModel TopTenByRating { get; set; }
        public MovieListViewModel TopTenByDate { get; set; }
    }
    
    public ActionResult Index()
    {
        var model = new HomeViewModel();
    
        model.TopTenByDate =
            _db.Movies
                .OrderByDescending(m => m.DateEntered)
                .Take(10)
                .Select(m => new MovieListViewModel 
                {
                    Id = m.Id,
                    Title = m.Title,
                    Genre = m.Genre,
                    ReleaseDate =  m.ReleaseDate,
                    CountOfReviews = m.Reviews.Count()
                });
    
        model.TopTenByRating = // something else
    
        return View(model);
    }
    

    对于更复杂的场景,我更喜欢dedicated composer 负责设置视图模型(而不是在动作方法中拥有所有逻辑)。

    对于像这样的简单场景,在控制器中进行设置是最简单的方法。如果您发现自己需要重用查询逻辑,请考虑将其抽象为辅助类。

    【讨论】:

      【解决方案4】:

      另一种方法是创建主视图并让它呈现 2 个操作方法的结果,返回 2 个分视图,每个分视图键入到一个模型中。

      【讨论】:

        【解决方案5】:

        你有不同的选择,你可以使用它们中的任何一个

        使用 ViewModel

        对于视图模型,您必须创建一个类,在此类中您将定义所有模型作为该类的属性。这里有两个类。

        public class EmployeeDetails
        {
            [Required]
            [Display(Name = "Name")]
            public string Name { get; set; }
        
        }
        
        public class Employee
        {
            public int Id { get; set; }
        }
        

        这是视图模型

        public class ViewModel
        {
            public Employee emp { get; set; }
            public EmployeeDetails empdet{ get; set; }
        }
        

        现在在 Controller 中你会这样做

        public ActionResult About()
        {
                ViewModel vm = new ViewModel();
                vm.emp = new Employee();
                vm.empdet = new EmployeeDetails();
                return View(vm);
        }
        

        你会收到这样的

        @model ViewModel
        

        使用元组

        元组用于存储不同的类型。您可以将所需的类对象存储在其中并传递给视图

        在控制器中

        Tuple<int, string> tuple = new Tuple<int, string>(1, "Hello world");
        return View(tuple);
        

        你会收到这样的

        @model Tuple<int,string>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-09
          • 1970-01-01
          • 2016-08-30
          相关资源
          最近更新 更多