MVC4两个下拉一个视图

时间:2015-04-23 14:57:25

标签: sql asp.net-mvc entity-framework asp.net-mvc-4

我有一个问题,我似乎无法弄清楚如何从两个不同的模型中获取数据并在视图中填充两个不同的下拉菜单。我对MVC很新,所以请善待,我只是在学习。

第一个产品型号:

public partial class Materials_Product
{
    public Materials_Product()
    {
        this.Materials_PackerProduct = new HashSet<Materials_PackerProduct>();
    }
    public short MatProdID { get; set; }
    public string Product { get; set; }
    public string Size { get; set; }  
    public virtual ICollection<Materials_PackerProduct> Materials_PackerProduct { get; set; }
}

第二种模式:

public partial class Materials_Packer
{
    public Materials_Packer()
    {
        this.Materials_PackerProduct = new HashSet<Materials_PackerProduct>();
    }
    public short MatPackID { get; set; }
    public string PackerName { get; set; }
    public string Location { get; set; }
    public virtual ICollection<Materials_PackerProduct> Materials_PackerProduct { get; set; }
}

在我的控制器中分配方法:

public ActionResult Assign()
{
    ViewBag.CategoryList = new SelectList(db.Materials_Product.ToList(), "MatProdID", "Product");
    ViewBag.ProductList = new SelectList(
        (from s in db.Materials_Product.ToList() select new
        {
            MatProdID = s.MatProdID,
            Product = s.Product + " " + s.Size
        }),
        "MatProdID",
        "Product");
    ViewBag.UserList = new SelectList(db.Materials_Packer.ToList(), "MatPackID", "PackerName");
    return View();
}

的DbContext:

public partial class FreshouseSalesEntities : DbContext
{
    public FreshouseSalesEntities() : base("name=FreshouseSalesEntities")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }
    public DbSet<Materials_Packer> Materials_Packer { get; set; }
    public DbSet<Materials_Product> Materials_Product { get; set; }
    public DbSet<Materials_PackerProduct> Materials_PackerProduct { get; set; }
    public DbSet<Materials_Vendor> Materials_Vendor { get; set; }
    public DbSet<Materials_Log> Materials_Log { get; set; }
    public DbSet<BigViewModel> BigViewModel { get; set; }
}

我的观点:

@model BagInventory.Models.Materials_Product
//I wish to  do something like @model BagInventory.Models.Materials_Packer but cannot since I believe I can only inherit one class
@{
    ViewBag.Title = "Assign";
}
<h2>Assign</h2>
@Html.DropDownListFor(model => model.MatProdID, ViewBag.ProductList as IEnumerable<SelectListItem>)
<br />
<select id ="sltProduct">
    @foreach (var item in ViewBag.ProductList) { 
        <option>@item.MatProdID</option>
    }
</select>

我无法在视图中加载两个模型....

我读到你可以创建另一个包含两个模型属性的模型......它看起来如下(并且不起作用):

public class BigViewModel
{
    public Materials_Packer Materials_Packer { get; set; }
    public Materials_Product Materials_Product { get; set; }
}

非常感谢任何指导或指示。

编辑:

以下是我尝试使用'BigViewModel' - 也就是一个类中的两个数据模型:

public ActionResult Assign()
{
    ViewBag.ProductList = new SelectList(db.BigViewModel.ToList(), "MatProdID", "Product");
    ViewBag.UserList = new SelectList(db.BigViewModel.ToList(), "MatPackID", "PackerName");
    return View();
}

更新了视图:

@model BagInventory.Models.BigViewModel

@{
    ViewBag.Title = "Assign";
}

<h2>Assign</h2>
@Html.DropDownListFor(model => model.Materials_Product.MatProdID, ViewBag.ProductList as IEnumerable<SelectListItem>)
<br />
@Html.DropDownListFor(model => model.Materials_Packer.MatPackID, ViewBag.ProductList as IEnumerable<SelectListItem>)

2 个答案:

答案 0 :(得分:1)

view bag有它的用途,但你真的想避免它。将模型更改为

public class BigViewModel
{
    public Materials_Packer mPacker { get; set; }
    public Materials_Product mProduct { get; set; }
    SelectList ProductList { get; set; }
    SelectList UserList { get; set; }
}

我建议不要使用类名作为实例名称。我曾经遇到过编译器因此而感到困惑的问题。 然后在你的控制器上你可以设置列表

public ActionResult Assign() {
    BigViewModel vm = new BigViewModel();
    vm.ProductList = new SelectList(db.BigViewModel.ToList(), "MatProdID", "Product");
    vm.UserList = new SelectList(db.BigViewModel.ToList(), "MatPackID", "PackerName");
    return View(vm);
}

您的下拉菜单现在将更改为

@Html.DropDownListFor(model => model.Materials_Product.MatProdID, Model.ProductList)

答案 1 :(得分:1)

您似乎遇到的问题是Model View的概念概念。模型视图控制器旨在表示超文本传输​​协议的无状态特性。因此,Model本质上应代表页面的数据。

理论上你可以使用Html.RenderAction,这将直接写入底层的响应流。因此,您的部分视图实际上会通过Razor调用以下内容:

@{ Html.RenderAction("Model", "View"); }

但是,我不确定这对您的架构是否理想。如果您想了解有关上述方法的更多信息,可以找到一个很好的解释here

否则其他方法将类似于以下内容:

public class Packer
{
     public int Id { get; set; }
     public string Company { get; set; }
}

public class Product
{
     public int Id { get; set; }
     public string Name { get; set; }
}

在这个阶段,我们有两个不同的独立模型。这会产生 Packer Product 的特定信息。所以我们要做的就是做一个更大的模型来体现这些较小的独特模型。

public string Shipping
{
     private List<Packer> packer;
     private List<Product> product;
     public Shipping(List<Packer> packer, List<Product> product)
     {
          this.packer = packer;
          this.product = product;
     }

     public List<Packer> Package
     {
          get { return this.packer; }
          set { this.packer = value; }
     }

     public List<Product> Products
     {
          get { return this.product; }
          set { this.product = value; }
     }
}

以上将创建一个Shipping模型,其中包含两个截然不同的模型。因此,当您的 Controller 调用您的服务或域层时,它将构建以下 shipping 对象。

从那个阶段开始,您的Controller只会将 Shipping 传递给它,它将显示在 View State 中。查看上述方法的最简单方法,但不建议在Controller中执行此操作:

[HttpGet]
public ActionResult Example()
{
     var products = new List<Product>();
     var packers = new List<Packer>();
     using(var connection = new SqlConnection(...))
          using(var command = new SqlCommand(query, connection))
          {
               // Query would grab all your data.
               using(var reader = command.ExecuteReader())
                    while(reader.Read())
                    {
                         var packer = new Packer();
                         var product = new Product();

                         // Build Your Model

                         packers.Add(packer);
                         products.Add(product);
                    }
          }

     var shipping = new Shipping(packers, products);
     return View(shipping, "Index");
}

这将是如何实现所述目标的前提。希望这会帮助你。我还建议不要使用ViewBag,因为它有可能在未来使维护变得困难。