views:

799

answers:

1

Table Product
Product Id
Product Name

Table ProductSupplier
ProductSupplierId
ProductId SupplierId

Table Supplier
SupplierId
SupplierName

I have the above 3 tables in my database, ProductSupplier is the lookup table. Each Product can have many suppliers. I am using Entity Framework.

Using Web Forms it was fairly easy to display a Product on a web page and bind a repeater with the suppliers information.

Also, with Web Forms it was easy to Add new Product and suppliers, the linkage seemed easy.

How do you do this sort of functionality in MVC?
In the Create View below, I want to be able to Add the Supplier as well.
Is there a better approach that I might be missing here?
This is how I did it with Web Forms.

Beyond the code below I am totally lost. I can show data in a list and also display the Suppliers for each Product, but how do I Add and Edit. Should I break it into different views? With Web Forms I could do it all in one page.

namespace MyProject.Mvc.Models
{
  [MetadataType(typeof(ProductMetaData))]
  public partial class Product
  {
    public Product()
    {
      // Initialize Product
      this.CreateDate = System.DateTime.Now;
    }
}

public class ProductMetaData
{
  [Required(ErrorMessage = "Product name is required")]
  [StringLength(50, ErrorMessage = "Product name must be under 50 characters")]
  public object ProductName { get; set; }

  [Required(ErrorMessage = "Description is required")]
  public object Description { get; set; }
}

public class ProductFormViewModel
{
  public Product Product { get; private set; }
  public IEnumerable<ProductSupplier> ProductSupplier { get; private set; }

  public ProductFormViewModel()
  {
      Product = new Product();
  }

  public ProductFormViewModel(Product product)
  {
      Product = product;
      ProductSupplier = product.ProductSupplier;
  }
 }
}

ProductRepository

public Product GetProduct(int id)
{
  var p = db.Product.FirstOrDefault(por => por.ProductId == id);
  p.ProductSupplier.Attach(p.ProductSupplier.CreateSourceQuery().Include("Product").ToList());

        return p;
    }

Product Create View

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"  
Inherits="System.Web.Mvc.ViewPage<MyProject.Mvc.Models.ProductFormViewModel>" %>
<%= Html.ValidationSummary("Please correct the errors and try again.") %>
<% using (Html.BeginForm()) {%>

 <fieldset>
    <legend>Fields</legend>

    <div class="editor-label">
        <%= Html.LabelFor(model => model.Product.ProductId) %>
    </div>
    <div class="editor-field">
        <%= Html.TextBoxFor(model => model.Product.ProductId) %>
        <%= Html.ValidationMessageFor(model => model.Product.ProductId) %>
    </div>

    <div class="editor-label">
        <%= Html.LabelFor(model => model.Product.ProductName) %>
    </div>
    <div class="editor-field">
        <%= Html.TextBoxFor(model => model.Product.ProductName) %>
        <%= Html.ValidationMessageFor(model => model.Product.ProductName) %>
    </div>

    <div class="editor-label">
        <%= Html.LabelFor(model => model.Product.Description) %>
    </div>
    <div class="editor-field">
        <%= Html.TextBoxFor(model => model.Product.Description) %>
        <%= Html.ValidationMessageFor(model => model.Product.Description) %>
    </div>            
    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset>

<% } %>
+1  A: 

the best way is to create a ViewModel this is a model that would consist of a Instance of product, and instance of productSupplier and and instance of supplier. when you create a view you strongly type to your new ViewModel that would then create all the fields needed as you have done above.

to ease complication with Add and Edit i find that creating an EditorTemplates folder and then your models own editor template helps, when it comes to creating the editors template you would have something like this:

public ActionResult EditProduct(int id)
{
  var model = new ProductViewModel{ productInfo = product.SingleOrDefault(x => x.prodid==id,
  Suppliers = Suppliers.all(),
  ProductSuppliers = ProdSuppliers.All()
)};
return(model);
}

you would then only have to deal with what supplier needs to be selected, this is the ID from your productInfo, again using the EditorTemplate to save on duplicating work and bugs. above should give you a general idea of where to start with this, thats if i am on the right track here?

if i am way off base here then please clarify

minus4
may i also add add that with editor templates, EditProduct will post to EditProduct, so create another actionResult but with a post attribute and same goes for create
minus4