【问题标题】:ASP MVC, mutiple models with single controller / view with EFASP MVC,带有单个控制器的多个模型/带有 EF 的视图
【发布时间】:2013-02-04 18:55:03
【问题描述】:

有人可以向我解释如何在单个视图中使用多个模型,其中每个模型代表一个数据库表吗?

我目前所做的是为每个模型创建一个模型文件。

示例模型:

[Table("Order")]
public class OrderModel
{
    [Key, Column(Order = 0)]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int OrderID { get; set; }

    [Key, Column(Order = 1)]
    public int UserID { get; set; }
    public UserProfile Account { get; set; }

    public DateTime Date { get; set; }
    public int ShipLocation { get; set; }
    public string PONumber { get; set; }

    public int StatusID { get; set; }
    public StatusModel Status { get; set; }
}

这是包含所有模型以在单个控制器/视图中使用的另一个模型。

public class OrderPlacementModel
{
    public OrderModel OrderChild { get; set; }
    public OrderItemsModel OrderItemsChild { get; set; }
    public StatusModel StatusChild { get; set; }
    public MaterialsModel MaterialsChild { get; set; }
    public CategoryModel CategoryChild { get; set; }
    public PackModel PackChild { get; set; }
}

【问题讨论】:

  • 您能否进一步详细说明这个问题? “使用多个模型”是什么意思?这是否意味着显示、编辑等?

标签: asp.net-mvc entity-framework


【解决方案1】:
public ActionResult PlaceOrder()
{
  var viewModel = new OrderPlacementModel
  {
    OrderChild = new OrderModel(),//or fetch this object from your data source
    OrderItemsChild = new OrderItemsChild(),
    //...etcetera
  };
  return View(viewModel);
}

编辑

或者,如果您将视图强输入到 List<OrderPlacementModel> 而不是单个实例,您可以执行类似的操作:

public ActionResult PlaceOrder()
    {
      var viewModel = new List<OrderPlacementModel>();
      var model = new OrderPlacementModel
      {
        OrderChild = new OrderModel(),//or fetch this object from your data source
        OrderItemsChild = new OrderItemsChild(),
        //...etcetera
      };
      viewModel.Add(model);
      //lather, rinse, repeat for however many instances you need to send to your view.
      return View(viewModel);
    }

【讨论】:

  • 好的,我遇到的问题是我收到以下错误:传入字典的模型项的类型为“Test2012.Models.OrderPlacementModel”,但此字典需要类型为模型项'System.Collections.Generic.IEnumerable1[Test2012.Models.OrderPlacementModel]'. Here is my Index view: code`@model IEnumerable @{ ViewBag.Title = "Index"; }

    索引

    @foreach(模型中的变量){ }
    @item.MaterialsChild
  • @1tufgt 编辑答案以解决您的评论
  • 好的,如果我的模型不是强类型为 IEnumerable,那么设置视图的正确方法是这样我可以从子模型中提取特定值吗? code@model Test2012.Models.OrderPlacementModel @{ ViewBag.Title = "Index"; }

    索引

    @{ var materials = Model.MaterialsChild.ToList(); foreach(var item in materials) {
    @item.Name
    } }
  • 您将如何迭代 Materials Child?它似乎不是 IEnumerable。
  • OrderPlacementModel 我已经完成了以下操作。如果你看材料模型。 code public class OrderPlacementModel { public OrderModel OrderChild { get;放; } 公共 OrderItemsModel OrderItemsChild { 获取;放; } 公共状态模型 StatusChild { 获取;放; } public List MaterialsChild { get;放; } 公共 CategoryModel CategoryChild { get;放; } 公共 PackModel PackChild { 获取;放; } }
【解决方案2】:

理想情况下,您应该为视图创建一个视图模型,其中包含您需要通过视图公开的每个模型的字段。然后,您可以将它们映射到您的控制器中。我会让您的映射类完全不了解您的视图模型。让您的视图独立于您的数据模型。

public class OrderViewModel
{
    public int OrderId { get; set; }
    public int UserId { get; set; }
    public DateTime Date { get; set; }
    public int ShippingLocation { get; set; }

    public List<ItemViewModel> Items { get; set; }
}

public class ItemViewModel
{
    public int ItemId { get; set; }
    public int Title { get; set; }
}

请注意我是如何为订单创建视图模型的,并且 - 为了允许订单有多个项目 - 将这些项目分离到一个单独的模型类中。现在,您可以将视图键入OrderViewModel,并根据需要使用ItemViewModel 的多个实例。

然后,您可以将视图模型从控制器映射到数据库实体:

[HttpPost]
public ActionResult ConfirmOrder (OrderViewModel model)
{
    if (ModelState.IsValid)
    {
        foreach (ItemViewModel item in model.Items)
        {
            /* Create instance of OrderItemsModel (or whatever your
            DB mapping class is), populate with appropriate data
            from 'item' and commit to database. */
        }

        OrderModel order = new OrderModel();
        order.OrderId = model.OrderId;
        order.UserId = model.UserId;
        order.Date = model.Date;
        order.ShipLocation = model.ShippingLocation;

        /* TODO: Commit new order to database */

    }
}

以这种方式做事会给您的初始开发时间增加一点开销,但可以让您获得更大的灵活性,因为您不必将所有视图都塑造成实体类的形状。

【讨论】:

  • 但我最初使用模型来设置我的代码优先 ef 数据库。
  • 这很好,但是您用于映射数据库表的模型不应该是您传递给视图的模型 - 您应该为此拥有专用的视图模型并将属性值从一个移动到其他在你的控制器中,就像我提供的代码一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多