在一个控制器中使用两个模型

本文关键字:两个 模型 控制器 一个 | 更新日期: 2023-09-27 18:15:09

我目前有一个应用程序,其主页显示了基于"创建"或输入数据库的日期的十部电影的列表。我还想根据每部电影的评分显示前十部电影的列表。是否有一种方法来传递另一个模型或改变我当前的ViewModel来做到这一点?这是我的Home Controller的Index部分:

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

在一个控制器中使用两个模型

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

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作为您的模型,并根据需要使用您的两个列表

创建另一个视图模型,为两个列表添加两个属性:

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

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

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

对于更复杂的场景,我更喜欢一个专门负责设置视图模型的编写器(而不是在操作方法中包含所有逻辑)。

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

另一种方法是创建主视图,并让它呈现2个操作方法的结果,返回2个部分视图,每个视图都属于一个模型。

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

使用ViewModel

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

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

这是viewmodel

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

使用元组

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

在控制器

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

考虑到你会收到这样的礼物

@model Tuple<int,string>