EF和CheckboxFor

时间:2013-07-05 15:47:24

标签: asp.net-mvc entity-framework razor checkboxfor

基本上我想要一个包含所有者详细信息的视图。 所有者可以有多种类型的车辆(或无),可以使用复选框进行选择:

The Index View

提交时,必须更新数据库,因为下次在<视图中显示所有者时,所有者必须选中正确的复选框。

我不确定如何构建我的EF模型,并且不确定我是否正确链接它以获得我想要的结果。

我不希望将车辆类型硬编码为所有者对象中的字段,因为有很多车辆安静。

有人能指出我如何链接这些模型的正确方向吗? 我在数据库中需要两个或三个表吗?

这就是我现在所拥有的,但它可能是错误的。如果您有任何想法,请立即停止阅读以避免混淆。 欢迎提出任何意见!

模特:

public class Vehicle
{
    public int VehicleID { get; set; }
    public string Name { get; set; }
}

public class Owner
{
    public int OwnerID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<OwnerVehicle> OwnerVehicles { get; set; }
}

public class OwnerVehicle
{
  public int OwnerVehicleID { get; set; }

  public bool Ticked { get; set; }
  //Not sure if this is needed, because ticked will always be true
  //I delete OwnerVehicle if not needed

  public int OwnerID { get; set; }
  public virtual Owner Owner { get; set; }

  public int VehicleID { get; set; }
  public virtual Vehicle  Vehicle { get; set; }
}

控制器:

public ActionResult Index()
    {
        //prepopulate Owner objects on the fly for this example, in my project it would fetched/created with EF into database
        Owner owner = getOwner();
        return View(owner); // we return the owner to view
    }

    public Owner getOwner()
    {
        //Create a owner
        Owner owner = new Owner() { OwnerID = 1, Name = "JACK" };

        //Create a list of vehicles
        List<Vehicle> Vehicles = new List<Vehicle>();
        Vehicles.Add(new Vehicle() { VehicleID = 1, Name = "I have a car"});
        Vehicles.Add(new Vehicle() {VehicleID = 1, Name = "I have a bike" });

        //the owner doesnt have any vehicles yet, therefor object OwnerVehicle is null at the moment

        return owner;
    }

    [HttpPost]
    public ActionResult Index(Owner owner)
    {   
        //at this point, the owner needs have his list of Vehicles linked, and written to database
        //
        //ToDO
        //return View();
    }

下面的视图不会编译,因为我迷路了。
Index.cshtml

    @model Owner
    @using (Html.BeginForm())
    {
          <div class="editor-field">
                @Html.EditorFor(model => model.OwnerVehicles)
            </div>
    }

EditorTemplates / OwnerVehicles.cshtml

    @model OwnerVehicle
    <div>
        @Html.CheckBoxFor(x => x.Ticked)
        @Html.LabelFor(x => x.TODO, Model.TODO)
        @Html.HiddenFor(x => x.TODO)
    </div>

2 个答案:

答案 0 :(得分:2)

我会创建一个对象来帮助呈现您要输出的内容。它将在“模型”中,但不会以任何方式映射到数据库。它看起来像这样:

public class VehicleHelper //or whatever you would like to call it...
{
  public Vehicle Vehicle { get; set; }
  public bool Ticked { get; set; }
}

然后,您的Owner会列出这些VehicleHelpers,如下所示:

public class Owner
{
  //include the properties you listed here...

  [NotMapped]
  public IEnumerable<VehicleHelper> VehicleHelpers { get; set; }
}

然后Controller会根据需要填充VehicleHelpers属性:

public ActionResult Edit(int id)
{
  MyContext db = new MyContext();
  Owner owner = db.Owners.FirstOrDefault(o => o.OwnerID == id);
  if (owner == null) thrown new Exception("Invalid Owner ID");
  owner.VehicleHelpers = db.Vehicles
    .Select(v => new VehicleHelper() { Vehicle = v, Ticket = false });
  foreach (Vehicle ownedVehicle in owner.OwnerVehicles.Select(ov => ov.Vehicle))
  {
    VehicleHelper helper = owner.VehicleHelpers
      .FirstOrDefault(vh => vh.Vehicle == ownedVehicle);
    if (helper == null) continue;
    helper.Ticked = true;
  }
  return View(owner);
}

[注意:以下部分是我不确定的确切语法,惯例等,因为我自己只是在学习MVC和Razer,但它应该很接近。随意编辑或建议编辑。 )]

然后你会有VehicleHelper的编辑器模板,它看起来像这样:

@model VehicleHelper
<div>
  @Html.CheckBoxFor(vh => vh.Ticked)
  @model.Vehicle.Name
  @Html.HiddenFor(vh => vh.Vehicle.VehicleID)
</div>

我希望至少可以帮助您指明正确的方向。 ;)

答案 1 :(得分:0)

CptRobby帮助我更深入地抓取网页,发现我的问题与this one重复了

Ciaran Bruen创建了一个很棒的教程,可以找到here,页面左侧有一个可下载的解决方案。

它显示了如何创建多对多关系,复选框和更新数据库。