2012-04-06 87 views
3

我想使用dropdownList与modelId和categoryId两个外键。 我正在使用ViewBag和selectList。ViewBag多个SelectList下拉列表

public ActionResult Create() 
    { 
     ViewBag.categoryId = new SelectList(db.Category, "categoryId", "name"); 
     ViewBag.modelId = new SelectList(db.Model, "modelId", "name"); 
     return View(); 
    } 

    // 
    // POST: /Product/Create 

    [HttpPost] 
    public ActionResult Create(Product product) 
    { 
     if (ModelState.IsValid) 
     { 
      db.Product.Add(product); 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     ViewBag.categoryId = new SelectList(db.Category, "categoryId", "name", product.categoryId); 
     ViewBag.modelId = new SelectList(db.Model, "modelId", "name", product.modelId); 
     return View(product); 
    } 

这里是我的Create.cshtml。

<div class="editor-label"> 
     @Html.LabelFor(model => model.Category) 
    </div> 
    <div class="editor-field"> 
     @Html.DropDownList("categoryId", "--Select--") 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.Model) 
    </div> 

    <div class="editor-field"> 
     @Html.DropDownList("modelId", "--Select--") 
    </div> 

当我按下提交按钮,错误上来, “具有相同键的项已被添加” 是什么问题呢?在模型中有问题吗?

这是我的模特。

--Prodruct.cs-- 

public class Product 
{ 
    [Key] public int productId { get; set; } 

    [Required(ErrorMessage = "Please select category")] 
    public int categoryId { get; set; } 

    [Required(ErrorMessage = "Please select model")] 
    public int modelId { get; set; } 

    [DisplayName("Model name")] 
    public String model { get; set; } 

    public virtual Category Category { get; set; } 
    public virtual Model Model { get; set; } 
} 

--Category.cs-- 
public class Category 
{ 
    [Key] public int categoryId { get; set; } 
    public String name { get; set; } 
} 

--Model.cs-- 
public class Model 
{ 
    [Key] public int modelId { get; set; } 
    public String name { get; set; } 
} 

--RentalDB.cs-- 
public class rentalDB : DbContext 
{ 
    public DbSet<Product> Product { get; set; } 
    public DbSet<Model> Model { get; set; } 
    public DbSet<Customer> Customer { get; set; } 
    public DbSet<Order> Order { get; set; } 
    public DbSet<Cart> Cart { get; set; } 
    public DbSet<Category> Category { get; set; } 
    public DbSet<OrderDetails> OrderDetails { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 
    } 
} 

哪里出错了?创建中的索引页面可以获取类别数据和模型数据。但是,当我提交时,它有错误,'已添加具有相同密钥的项目'。 你能帮我解决问题吗? 谢谢。

- 添加更多编码 -

我正在使用此LINQ。可能这里有问题。

如何在此处添加“模型”实体?

var product = from a in db.Product.Include(a => a.Category) 
         select a; 
+0

我加了一个关于如何完成的详细答案。 – 2012-04-06 13:24:55

回答

2

这是我怎么会做呢..

我建议你不要把你的域模型的观点,而是为每个视图创建一个视图模型。这样做,你将只包括屏幕上需要的东西。

为您创建视图中创建一个新的视图模式:

public class ProductCreateViewModel 
{ 
    // Include other properties if needed, these are just for demo purposes 

    public string Name { get; set; } 
    public string SKU { get; set; } 
    public string LongDescription { get; set; } 

    // This is the unique identifier of your category, 
    // i.e. foreign key in your product table 
    public int CategoryId { get; set; } 
    // This is a list of all your categories populated from your category table 
    public IEnumerable<Category> Categories { get; set; } 

    // This is the unique identifier of your model, 
    // i.e. foreign key in your product table 
    public int ModelId { get; set; } 
    // This is a list of all your models populated from your model table 
    public IEnumerable<Model> Models { get; set; } 
} 

分类等级:

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

模型类:

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

在您创建视图,您将有以下:

@model MyProject.ViewModels.ProductCreateViewModel 

@using (Html.BeginForm()) 
{ 
    <table> 
      <tr> 
       <td><b>Category:</b></td> 
       <td> 
        @Html.DropDownListFor(x => x.CategoryId, 
         new SelectList(Model.Categories, "Id", "Name", Model.CategoryId), 
         "-- Select --" 
        ) 
        @Html.ValidationMessageFor(x => x.CategoryId) 
       </td> 
      </tr> 
      <tr> 
       <td><b>Model:</b></td> 
       <td> 
        @Html.DropDownListFor(x => x.ModelId, 
         new SelectList(Model.Models, "Id", "Name", Model.ModelId), 
         "-- Select --" 
        ) 
        @Html.ValidationMessageFor(x => x.ModelId) 
       </td> 
      </tr> 
    </table> 

    <!-- Add other HTML controls if required and your submit button --> 
} 

你创建的操作方法:

public ActionResult Create() 
{ 
    ProductCreateViewModel viewModel = new ProductCreateViewModel 
    { 
      // Here you do database calls to populate your dropdowns 
      Categories = categoryService.GetAllCategories(), 
      Models = modelService.GetAllModels() 
    }; 

    return View(viewModel); 
} 

[HttpPost] 
public ActionResult Create(ProductCreateViewModel viewModel) 
{ 
    // Check that viewModel is not null 

    if (!ModelState.IsValid) 
    { 
      viewModel.Categories = categoryService.GetAllCategories(); 
      viewModel.Models = modelService.GetAllModels(); 

      return View(viewModel); 
    } 

    // Mapping 
    Product product = ... // Do your mapping here 

    // Insert product in database 
    productService.Insert(product); 

    // Return the view where you need to be 
} 

我也建议你使用AutoMapper做映射你的域模型和视图模型之间。我也建议你看看Fluent Validation来照顾你的视图模型验证。

我希望这会有所帮助。

修订ANSWER

这是用来让所有的类别可能看起来像这样的服务:

public class CategoryService : ICategoryService 
{ 
    private readonly ICategoryRepository categoryRepository; 

    public CategoryService(ICategoryRepository categoryRepository) 
    { 
      // Check if category repository is not null, throw exception if it is 

      this.categoryRepository = categoryRepository; 
    } 

    public IEnumerable<Category> GetAllCategories() 
    { 
      return categoryRepository.GetAllCategories(); 
    } 
} 

categoryRepository由Autofac注入。

分类服务接口:

public interface ICategoryService 
{ 
    IEnumerable<Category> GetAllCategories(); 
} 

我目前还在第一次使用Entity Framework 4.1代码。

我的类别库:

public class CategoryRepository : ICategoryRepository 
{ 
    MyContext db = new MyContext(); 

    public IEnumerable<Category> GetAllCategories() 
    { 
      return db.Categories 
       .OrderBy(x => x.Name); 
    } 
} 

我的类别库接口:

public interface ICategoryRepository 
{ 
    IEnumerable<Category> GetAllCategories() 
} 
+0

谢谢你的回复。你知道任何ViewModel的例子吗?我想我需要了解ViewModel的更多细节。如果你知道一些网站,请告诉我。我无法正确理解ViewModel。如果您已经了解了ViewModel教程,请告诉我。谢谢! – wholee1 2012-04-06 14:43:02

+0

我的荣幸。只是谷歌它。基本上,视图模型仅包含要在视图中使用的字段,例如,如果您想添加新用户,那么您的字段只有名字,姓氏和年龄,而不是在用户对象中使用所有内容。 – 2012-04-06 14:50:25

+0

我想通过使用ViewModel添加它的字段与原始实体中的字段名称相同吗?我想了解ViewModel是如何工作的。在你的编码中,'viewModel.Categories = categoryService.GetAllCategories();'我如何声明categoryService? – wholee1 2012-04-06 14:57:32

0
public class Test 
{ 
    rentalDB db = new rentalDB(); 
    public Product LoadProductById(int pId) 
    { 
     return db.Products.Include(p => p.Model).Include(p => p.Category).Where(p => p.productId == pId).SingleOrDefault(); 
    } // To get specific product. 

    public IEnumerable<Product> LoadAllProducts() 
    { 
     return db.Products.Include(p => p.Model).Include(p => p.Category).ToList(); 
    } // To get all products. 
} 

我已经改变了你的DbSet到产品使其更加清晰。这是您如何加载一个产品或所有产品的所有参考,以便迭代它们。