【问题标题】:ASP.NET MVC delete buttonASP.NET MVC 删除按钮
【发布时间】:2018-08-30 18:48:01
【问题描述】:

当我单击删除按钮时,出现此错误。

SqlException:DELETE 语句与 REFERENCE 约束“FK_Reserva_Quarto”冲突。冲突发生在数据库“GestãoHotel”、表“dbo.Reserva”、列“ID_Quarto”中。

有人知道原因吗?

控制器:

// GET: Quartos/Delete/5
public ActionResult Delete(int? id)
{
      if (id == null)
      {
          return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
      }

      Quarto quarto = db.Quarto.Find(id);

      if (quarto == null)
      {
           return HttpNotFound();
      }

      return View(quarto);
}

// POST: Quartos/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
     Quarto quarto = db.Quarto.Find(id);
     db.Quarto.Remove(quarto);
     db.SaveChanges();
     return RedirectToAction("Index");
}

查看:

<div class="table-responsive panel">
 <table class="table">
  <tbody>
     <tr>
        <td class="text-success"><i class="fa fa-list-ol"></i> Nº Quarto</td>
        <td>@Model.ID_Quarto</td>
      </tr>
      <tr>
        <td class="text-success"><i class="fa fa-bed"></i> Tipo de Quarto</td>
        <td>@Model.TipoQuarto</td>
      </tr>
    </tbody>
   </table>
</div>

<table class="table">
 <tbody>
  <tr>
     @using (Html.BeginForm())
     {
     @Html.AntiForgeryToken()
     <td class="text-center">
      <button type="submit" class="btn btn-danger btn-circle btn-xl" data-toggle="tooltip" title="Eliminar"> <i class="glyphicon glyphicon-ok"></i></button>
 <button type="button" onclick="location.href='@Url.Action("Index", "Quartos")'" class="btn btn-primary btn-circle btn-xl" data-toggle="tooltip" title="Voltar"><i class="glyphicon glyphicon-arrow-left"></i></button>
     </td>
      }
    </tr>
   </tbody>
 </table>

连接字符串:

<connectionStrings>
    <add name="Hotel" 
         connectionString="Data Source=DESKTOP-BC284NS\SQLEXPRESS;initial catalog=GestãoHotel;integrated security=True;" 
         providerName="System.Data.EntityClient" />
    <add name="HotelEntities" 
         connectionString="metadata=res://*/Models.BaseDados.GestãoHotel.csdl|res://*/Models.BaseDados.GestãoHotel.ssdl|res://*/Models.BaseDados.GestãoHotel.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=DESKTOP-BC284NS\SQLEXPRESS;initial catalog=GestãoHotel;integrated security=True;App=EntityFramework&quot;" 
         providerName="System.Data.EntityClient" />
</connectionStrings>

【问题讨论】:

  • 当你收到错误时,将鼠标悬停在 id 上并检查 id 是否有效
  • 检查 fk FK_Reserva_Quarto 的迁移类。您可能需要从级联更改OnDelete
  • 既然是数据库问题,请务必提及您正在使用的数据库以及 EF 提供程序
  • @NevilleNazerane 感谢您尝试帮助我。我已经编辑了帖子并将我的连接连接到数据库
  • @Navas - 就像 Neville 所说,你只是有一个外键约束阻止你进行级联删除。

标签: sql-server asp.net-mvc


【解决方案1】:

您必须先删除Reservas,然后才能删除Quarto,如下所示:

[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
     List<Reserva> Reservas = db.Reserva.Where(r => r.ID_Quarto == id).ToList();
     db.Reserva.RemoveRange(Reservas);

     Quarto quarto = db.Quarto.Find(id);
     db.Quarto.Remove(quarto);
     db.SaveChanges();
     return RedirectToAction("Index");
}

此外,对于永久解决方案,DbContext中添加以下配置,然后运行迁移并相应地更新数据库:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     base.OnModelCreating(modelBuilder);

     modelBuilder.Entity<Reserva>().HasRequired(j => j.Quarto)
                                   .WithMany(c => c.Reservas)
                                   .HasForeignKey(j => j.ID_Quarto).WillCascadeOnDelete(true);
}

希望您的问题能得到解决!

【讨论】:

  • 这是从 fluent API 设置级联的最简单方法吗?即使 fk 已经设置了数据注释?
  • 是的!这是!即使您没有使用数据注释设置外部属性,也没有问题。它将正确生成所有内容。
【解决方案2】:

我认为您对此有选择。 - 选项 1:使用 ON DELETE CASCADE - 选项 2:按正确顺序删除。这意味着您应该先删除 Reserva 中的行,然后删除 Quarto 中的行。

您可以按照此示例进行操作。希望能帮到你,我的朋友:))

//选项一:

ALTER TABLE <child_table> WITH CHECK 
ADD CONSTRAINT <fk_name> FOREIGN KEY(<column(s)>)
REFERENCES <parent_table> (<column(s)>)
ON DELETE CASCADE

选项 2:

// POST: Quartos/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            //Delete the rows from Reserva first
            var reservaObj = db.Reserva.Where(t => t.ID_Quarto == id).ToList();
            db.Reserva.RemoveRange(reservaObj);

            Quarto quarto = db.Quarto.Find(id);
            db.Quarto.Remove(quarto);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

【讨论】:

  • 只要他将 ef 与迁移一起使用,最好更新迁移而不是运行原始查询。此查询本身可以在迁移中运行。这在迁移数据库时会有所帮助
  • @NevilleNazerane:是的!感谢您的评论:d
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多