带有实体框架的 MVC 下拉列表

Posted

技术标签:

【中文标题】带有实体框架的 MVC 下拉列表【英文标题】:MVC Drop Down list with entity framework 【发布时间】:2014-12-27 02:07:35 【问题描述】:

我首先使用实体​​框架代码创建了一个 MVC 项目。我的模型只是一个收集信息的表格。

public class Application

    public int Id  get; set; 
    public string FirstName  get; set; 
    public string MiddleInitial  get; set; 
    public string LastName  get; set; 
    public int SSN  get; set; 
    public DateTime DOB  get; set; 
    public string Street  get; set; 
    public string City  get; set; 
    public string State get; set; 
    public string Zip  get; set; 
    public int HomePhone  get; set; 
    public int BusinessPhone  get; set; 
    public int MobilePhone  get; set; 

我的目标是创建一个包含所有状态的下拉列表,但我发现这非常困难,因为我已经通过带有视图和控制器的脚手架创建了数据库。有没有一种简单的方法可以做到这一点并将其与现有数据库联系起来?我几乎一整天都没有运气。对模型/控制器/视图包含的内容的概述/解释将是惊人的!


更新:我创建了一个名为“State”的新模型,其属性为“Id”和“StateName”,并在数据库中创建了一些状态。在 Create 操作方法中的“应用程序”控制器中,我有:

控制器

public ActionResult Create()
    

        ApplicationDbContext db = new ApplicationDbContext();
        this.ViewData["Id"] = new SelectList(db.States.ToList(), "Id", "StateName");
        return View();
    

查看

@html.DropDownList("Id")

现在的问题是我收到此错误“没有具有键 'Id' 的 'IEnumerable' 类型的 ViewData 项。”非常感谢帮助!

【问题讨论】:

问题是什么,如何从数据库中提取数据,或者在 UI 上显示? 嗯,我不确定该怎么做。我目前有一张申请表(上图)。我需要在设计器中手动创建另一个名为“States”的表还是先使用代码?之后,我需要知道如何提取数据,然后将其显示在我现有的表单上。 查看一些教程asp.net/mvc/overview/getting-started/… 我已经通过脚手架创建了表单,并拥有一个包含应用程序信息的现有数据库。我的问题是如何创建一个下拉列表并将其添加到我现有的表单中。 您需要有一个数据库表(或其他一些数据存储)来保存可用状态。然后,您获取它们,将它们分配给 SelectList 并使用 @Html.DropDownFor() 选择并将其分配给您的 State 属性。 【参考方案1】:

这很简单。将IEnumerable<SelectListItem> 属性添加到您的模型(这里我建议您创建一个可以与Application 具有完全相同属性的视图模型,并将以下代码作为属性包含在内)。然后您只需要构建列表并将其发送到您的视图

public IEnumerable<SelectListItem> States get; set; 

我假设您想从数据库中检索 State 值。以下是您的操作方法:

private IEnumerable<SelectListItem> GetAllStates()

    IEnumerable<SelectListItem> list = from s in db.Applications
                                       select new SelectListItem
                                       
                                           Selected = false,
                                           Text = s.State,
                                           Value = s.State
                                       ;
    return list;

或者这个……

private IEnumerable<SelectListItem> GetAllStates()

    IEnumerable<SelectListItem> list = db.Applications.Select(s => new SelectListItem
                                       
                                           Selected = false,
                                           Text = s.State,
                                           Value = s.State
                                       );

    return list;

然后在你的行动中做这样的事情:

var app = new Application

    States = GetAllStates()
;

return View(app);

最后,在视图上使用 Razor 显示下拉列表,如下所示

@Html.DropDownListFor(m => m.State, Model.States, "--Select a State--")

第一个参数是要更新的模型的属性,第二个是数据列表,第三个是默认显示的信息

希望这会有所帮助。

【讨论】:

效果很好!谢谢【参考方案2】:

创建一个数据层来检索您想要的列表。然后使用EF获取所有状态。

//assuming you have a table of states..
var states = db.States();

状态表应该是唯一的状态列表。

var selectList = new List<SelectListItem>(); 
foreach(var thing in states)
    //if you got everything, thus the ID field for the value...   
   selectList.Add(new SelectListItem Text =thing.State, Selected = false, Value = thing.ID);

确保在您的 Viewmodel 类中 selectlist 是一个公共属性......并设置为您在上面所做的。您还需要为返回的视图选择提供一个字符串。

StatesSelectList = selectList;
public IEnumberable<SelectListItem> StatesSelectList get;set;
public string SelectedState get;set;

在你看来,这样做:

@Html.DropDownListFor(p=>Model.SelectedState, Model.StatesSelectList)

【讨论】:

当您创建第一个 Application 时会发生什么? application.select(p=&gt;p.State) 将是空的,您将永远无法添加新的 Application 我回答的第一句话是必须访问数据层。如果应用程序列表中没有任何内容,则由数据层来填充它。当然,操作正在使用数据库,对吗?如果不是,那么数据层必须确定提供第一组信息的方法。这是MVC中常见的模式(模型的初始化)...当控制器创建模型的实例并将其传回视图时实现。 再次完成你的逻辑。提示:状态需要单独的表:) 我没有展示操作初始化逻辑,你是对的。我可能通过展示视图模型实现并将所有内容都移至 VM 使他感到困惑。该示例还尝试显示分离的数据访问层,(第三个代码块可以移动到存储库类)。但是你是对的,VM 必须填充所有内容(在空 CTOR 中)才能使视图正常工作.. 我仍然不认为你明白。 Application 对象具有 State 属性。为了创建Application 并将其保存到数据库,您需要选择State。您正在查询 Application 表以获取状态。如果尚未创建 Applications,则状态集合为空,因此您无法分配状态,因此您无法保存它。它是第 22 条军规!只需编辑您的答案,它表明需要一个单独的 States 表,并且您从 States 表而不是 Application 表创建下拉列表【参考方案3】:

非常简单的代码一步一步

1) 在实体框架类中

var productsList = (from product in dbContext.Products
                     select new ProductDTO
                     
                       ProductId = product.ProductId,
                       ProductName = product.ProductName,
                       ).ToList();

2) 在控制器中

ViewBag.productsList = new EntityFrameWorkClass().GetBusinessSubCategoriesListForDD();

3) 在视图中

@Html.DropDownList("Product_ProductId", new SelectList(ViewBag.productsList, "ProductId", "ProductName"), new  @class = "form-control" )

@Html.DropDownListFor(m=>m.Product_ProductId, new SelectList(ViewBag.productsList , "ProductId", "ProductName"), new  @class = "form-control" )

【讨论】:

【参考方案4】:

我假设有一个具有 Id 和 StateName 属性的 States 模型。

将列表更改为 ViewData["State"] 以确保在 POST 上轻松绑定。

Id 是将在 POST 数据中发送的值,即.. State = Id。 StateName 将显示在 Select 列表中。 所以对于您的模型,这是不正确的,因为 State 是一个字符串。所以需要是

this.ViewData["State"] = new SelectList(db.States.ToList(), "StateName", "StateName");

那么在你看来

@Html.DropDownList("State")

【讨论】:

以上是关于带有实体框架的 MVC 下拉列表的主要内容,如果未能解决你的问题,请参考以下文章

数据库表的列中的值的下拉列表-MVC实体框架

带有 json 和 python 的依赖下拉列表

修复 URL 以返回带有 JsonResult 的下拉列表项 - MVC- C#

(转)基于MVC4+EasyUI的Web开发框架经验总结--在页面中应用下拉列表的处理

MVC,映射器将 ViewModel 传递给 CreateView 的问题

如何根据实体框架中的下拉列表选择项填充表单字段以进行更新?