Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 3 DropDownList用于使用MVC3创建新实体_Asp.net Mvc 3_Entity Framework_Razor_Html.dropdownlistfor - Fatal编程技术网

Asp.net mvc 3 DropDownList用于使用MVC3创建新实体

Asp.net mvc 3 DropDownList用于使用MVC3创建新实体,asp.net-mvc-3,entity-framework,razor,html.dropdownlistfor,Asp.net Mvc 3,Entity Framework,Razor,Html.dropdownlistfor,为了更好地理解MVC3和Razor的工作原理,我正在开发一个小应用程序。我使用的是MVC3,所有代码都是通过T4自动生成dbContext,通过Add Controller自动生成Controller,从EDMX模型自动生成Database 在我的模型中,我有一个简单的模型: 如您所见,ApplicationType基本上是一个枚举类型,因为EF4不支持枚举。因此,在我的ApplicationController中,我有: public ActionResult Create() {

为了更好地理解MVC3和Razor的工作原理,我正在开发一个小应用程序。我使用的是MVC3,所有代码都是通过T4自动生成dbContext,通过Add Controller自动生成Controller,从EDMX模型自动生成Database

在我的模型中,我有一个简单的模型:

如您所见,ApplicationType基本上是一个枚举类型,因为EF4不支持枚举。因此,在我的ApplicationController中,我有:

public ActionResult Create()
{
    ViewBag.AppTypes = new SelectList(db.ApplicationTypes.OrderBy(c => c.Type), "Id", "Type");
    return View();
} 

[HttpPost]
public ActionResult Create(Application application)
{
    if (ModelState.IsValid)
    {
        db.Applications.Add(application);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(application);
}
在我看来:

@Html.DropDownListFor(model => model.ApplicationType.Id, (SelectList)ViewBag.AppTypes, "Choose...")
现在我面临两个问题:

1未填充应用程序类型:

@Html.DropDownListFor只呈现一个简单的select,它填充ID,但不填充Type属性,如下面所示。抱歉,我不能发布图像,因为我是新来的:

在图片中,您可以看到ID是ok的,但Type是空的

我做错了什么

2重复数据

第二个问题是,如果在模拟正确工作流场景的调试期间手动填充Type属性,则ApplicationType将在数据库中复制,而不是仅引用旧注册表

那么,如何使@Html.DropDownListFor引用以前的现有项而不是创建新项

谢谢你的帮助

您是否尝试过:

@Html.DropDownListFor(model => model.ApplicationType.Id, m => m.ApplicationType.Type, "Choose...")

请注意第二个参数更改。

我认为您犯的错误是在视图中使用域模型,并假设在发布时整个模型应完全绑定并准备存储在数据库中。虽然可以在视图中使用域模型,但最好创建单独的视图模型

例如:

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

    public SelectList ApplicationTypeList { get; set; }
    public string ApplicationTypeId { get; set; }
}
在你看来:

@Html.DropDownListFor(model => model.ApplicationTypeId, Model.ApplicationTypeList , "Choose...")
在控制器中

[HttpPost]
public ActionResult Create(ApplicationViewModel model)
{
    if (ModelState.IsValid)
    {
        Application application = new Application()
        {
           Id = model.Id,
           Name = model.Name,
           ApplicationType = db.ApplicationTypes
              .First(a => a.Id == model.ApplicationTypeId);

        };
        db.Applications.Add(application);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(model);
 }

然后,可以将验证视图模型的ApplicationTypeId是否对应于实际应用程序类型作为modelstate验证的一部分。您可以使用加快将视图模型转换为域模型的过程。

谢谢,@mirezus!不幸的是,它不起作用,因为第二个参数需要一个,而不是一个lambda。通常,您可以将该项包装到selectlistitem内联中,即:新建selectlistitem{Text=m.TextToUse,Data=m.DataToUse}太棒了!所以我的问题不是代码本身,而是MVC的工作方式。这很容易理解和理解。顺便说一句,我使用的是另一种方法:public ActionResult CreateApplication应用程序{if ModelState.IsValid{int appTypeID=Convert.ToInt32ModelState[ApplicationType.Id].Value.AttemptedValue;application.ApplicationType=db.ApplicationTypes.Singles=>s.Id==appTypeID;我对这个解决方法感到不安。。。
[HttpPost]
public ActionResult Create(ApplicationViewModel model)
{
    if (ModelState.IsValid)
    {
        Application application = new Application()
        {
           Id = model.Id,
           Name = model.Name,
           ApplicationType = db.ApplicationTypes
              .First(a => a.Id == model.ApplicationTypeId);

        };
        db.Applications.Add(application);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(model);
 }