【问题标题】:Insert/Update Many to Many in an Entity Framework 6 Jointable在实体框架中插入/更新多对多 6 Jointable
【发布时间】:2015-12-08 01:03:52
【问题描述】:

我正在尝试在此 EF6-MVC 项目中插入和更新,但我无法正确执行。我真的需要你们的帮助,我将不胜感激。

假设我有这 3 张桌子:

类/表 1:Curso --> CursoId - nombreCurso

类/表 2:Modalidad --> ModalidadId - nombreModalidad

类/表 3:ModalidadCurso --> ModalidadId - CursoId(EF 自动创建)


让我们切入正题,下一个模型(简化版):

public class Curso
{
        public int CursoId{ get; set; }

        public string nombreCurso { get; set; }

        public virtual ICollection<Modalidad> Modalidades { get; set; }
}


public class Modalidad
{

        public int ModalidadId{ get; set; }

        public string nombreModalidad { get; set; }

        public virtual ICollection<Curso> Cursos { get; set; }
}



public class ItehlContext: DbContext
{
        public ItehlContext(): base("name=conexionItehl") { }

        public DbSet<Curso> Cursos { get; set; }

        public DbSet<Modalidad> Modalidades { get; set; }


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

            modelBuilder.Entity<Modalidad>()
             .HasMany(c => c.Cursos)
             .WithMany(i => i.Modalidades)
             .Map(t => t.MapLeftKey("codigoModalidad")
                 .MapRightKey("codigoCurso")
                 .ToTable("ModalidadCurso"));

        }
}

嗯,事情是,我正在尝试做下一件事,EF6 正在创建一个 ModalidadCurso 表,其中保存 ModalidadId 和 CursoId,作为传递类的 FK 的多对多关系。

但是当我尝试创建一个新的 Curso 实体时,我的 MVC-ViewForm 出现问题,因为它没有像预期的那样在 modalidadCurso 实体中创建 ForeignKeys。这几天我一直在研究这个小小的不便,它根本不起作用。

控制器创建 GET/POST

    // GET: /Curso/Create
    public ActionResult Create()
    {
        var cursos = new Curso();
        cursos.Modalidades = new List<Modalidad>();
        ListaModalidadesDropDownList(cursos);
        return View();
    }

    // POST: /Curso/Create
    // Para protegerse de ataques de publicación excesiva, habilite las propiedades específicas a las que desea enlazarse. Para obtener 
    // más información vea http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include="codigoCurso,nombreCurso")] Curso curso)
    {
        try
        {
            var nuevaModalidad = new List<Modalidad>();
            if (nuevaModalidad != null)
            {

                foreach (var modalidad in nuevaModalidad)
                {
                    var agregarModalidad = db.Modalidades.Find(modalidad);
                    curso.Modalidades.Add(agregarModalidad);

                }
            }

            if (ModelState.IsValid)
            {
                db.Cursos.Add(curso);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
        }

        catch (RetryLimitExceededException /* dex */)
        {
            //Log the error (uncomment dex variable name and add a line here to write a log.)
            ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
        }

        ListaModalidadesDropDownList(curso.Modalidades.First().codigoModalidad);
        return View(curso);
    }

我知道了:

Entity Insert Many-Many-Relationship

它在 Curso Table 中创建实体,没关系。

但是,在 FK-Many Many Relationship-ModalidadCurso 表中,它什么也没做。

我做错了什么??我是 Entity Framework 的初学者,但一切似乎都很好。

感谢您的帮助。

这是 Create.cshtml 文件(简化)

@model ItehlConsulting.Models.Itehl.Curso
@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken() 
   l.ValidationSummary(true)

        <div class="form-group">
            @Html.LabelFor(model => model.nombreCurso, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.nombreCurso)
                @Html.ValidationMessageFor(model => model.nombreCurso)
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2" for="codigoModalidad">Modalidad</label>
            <div class="col-md-10">
                @Html.DropDownList("codigoModalidad", String.Empty)
                @Html.ValidationMessageFor(model => model.Modalidades.First().nombreModalidad)
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Crear Curso" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

【问题讨论】:

  • 您的视图看起来如何?
  • 我应该发布所有视图吗?完成 Create.cshtml??
  • 看起来您的 opcionModalidades 作为一个空集合回来了。您是否在代码中放置了断点并检查它?
  • Code First 基于命名约定,目前我在这里没有命名约定,但我注意到你的类没有任何数据注释,上次我使用代码优先我在类中使用了数据注释。可能您必须注释类的主键。 entityframeworktutorial.net/code-first/… 多对多关系,我认为它与您所做的 fluent API 正确映射。
  • 您将代码中的opcionModalidades 发送到哪里?它不在视图中?

标签: c# asp.net-mvc entity-framework


【解决方案1】:

在您看来,您发送的是codigoModalidadnombreCurso。您必须将这些值发布到控制器。

替换这个:

public ActionResult Create([Bind(Include="codigoCurso,nombreCurso")] Curso curso)

为此:

public ActionResult Create(string nombreCurso, int codigoModalidad)

然后,在您的控制器动作中,您必须创建 Curso 并将其与 Modalidad 相关联:

[HttpPost]
public ActionResult Create(string nombreCurso, int codigoModalidad)
{
    Modalidad modalidad = new Modalidad();
    modalidad.ModalidadId = codigoModalidad;
    //if modalidad already exists in database, and you just want to make a relationship
    ctx.Entry(modalidad).State = EntityState.Unchanged; 
    //if modalidad does not exists in database, and you want to insert it
    //ctx.Entry(modalidad).State = EntityState.Added;

    Curso curso = new Curso();
    curso.nombreCurso = nombreCurso;
    curso.Modalidades.Add(modalidad); //add our existing modalidad to our new course

    ctx.Cursos.Add(curso);
    ctx.SaveChanges();
}

编辑 1

Curso 构造函数内部:

public Curso() 
{
    Modalidades = new HashSet<Modalidad>();   
}

在 Modalidad 构造函数内部:

public Modalidad()
{
     Cursos = new HashSet<Curso>();
}

希望对你有帮助!

【讨论】:

  • 谢谢fabio,我按照你的解释做了,但还是不行,好像“codigoModalidad”没有保存create.cshtml的值,我不知道怎么做,我试过了直接放置FK的项目。像这样:@Html.ValidationMessageFor(model => model.Modalidades.First().codigoModalidad) 但我得到了 NullReferenceException,所有的 codigoModalidad,也许如果我能得到关于如何处理多对多关系数据的信息具有剃刀网络表单的实体,我可以做到这一点,但仍然没有找到我需要做这件事的方法。 MVC 指南很棒,但我还是不明白。
  • 你是用一个下拉列表来表示modalidad,这意味着当你输入create.cshtml时,modalidad已经在数据库中创建了。我看到这段代码@Html.DropDownList("codigoModalidad", String.Empty) 为什么你要传递一个 "String.Empty" ?你应该传递一个项目集合
  • 根据 wiki “SelectExtensions.DropDownList Method (HtmlHelper, String)”只传递列表的字符串值,我传递的是一个空字符串,DropDownList 在网络表单中没有显示任何内容,直到被选中,然后它显示 Modalidades 列表。我怎样才能通过收藏??
  • 调试应用,看看nombreCursocodigoModalidad是否在控制器内部设置
  • 在构造函数 public ActionResult Create(string nombreCurso, string descriptcionCurso, string dirigido, double costoCurso, int horasCurso, int codigoModalidad),一切看起来都很好,但后来 Modalidad modalidad = new Modalidad(); modalidad.ModalidadId = codigoModalidad; ModalidadID 没有保存值,发生了什么?另一件事,DropDownList 方法正在为控制器之外的另一个方法设置 ListaModalidadesDropDownList();这是使用LINQ获取信息列表来填充DropDownList,不用担心GET Create,是POST Create prob在哪里
猜你喜欢
  • 1970-01-01
  • 2017-02-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-24
  • 1970-01-01
  • 2011-06-02
  • 2011-05-14
  • 1970-01-01
相关资源
最近更新 更多