【问题标题】:Why is it that when I delete from my database the id remains?为什么当我从数据库中删除时,id 仍然存在?
【发布时间】:2021-04-07 02:29:07
【问题描述】:

抱歉,我的问题可能有点含糊。我只是不知道如何正确表达它。

当我尝试从我的数据库中删除时,数据 id 仍然存在,当我向表中添加新数据时,id 继续增加。

我的控制器:

[HttpGet]
    public ViewResult Delete(int id)
    {
        var product = context.Products
                        .FirstOrDefault(c => c.ProductId == id);

        return View(product);
    }

    [HttpPost]
    public RedirectToActionResult Delete(Product product)
    {
        context.Products.Remove(product);
        context.SaveChanges();
        return RedirectToAction("List", "Product");
    }

我在哪里列出项目的视图:

@foreach (Product product in Model)
    {
        <tr>
            <td>@product.Code</td>
            <td>@product.Name</td>
            <td>$@product.Price</td>
            <td>@product.ReleaseDate</td>
            <td>
                <a asp-controller="Product" asp-action="Edit"
                   asp-route-id="@product.ProductId" class="btn btn-primary">Edit</a>
            </td>
            <td>
                <a asp-controller="Product" asp-action="Delete"
                   asp-route-id="@product.ProductId" class="btn btn-primary">Delete</a>
            </td>
        </tr>
    }

我对删除操作的看法:

<form asp-action="Delete" method="post">
<input type="hidden" asp-for="ProductId" />

<div>
    <button type="submit" class="btn btn-primary">Delete</button>
    <a asp-controller="Product" asp-action="List" class="btn btn-primary">Cancel</a>
</div>

我在这里做错了什么?或者如果没有任何问题,为什么它的行为方式与 id 字段一样。

【问题讨论】:

  • 自动递增的 ID 不会在删除时递减,如果这是您所要求的(不清楚)
  • @Charlieface 哦,我不知道。谢谢你告诉我。
  • 首先澄清一下你的问题:假设数据库有3个项目(id为1,2,3),你的意思是删除第三个项目后,再插入一个新的项目,新的id将是 4,而不是 3。这是您的问题吗?如果是这种情况,ID 列可能是标识列,因此它会自动增加数字而不重用该值。为防止这种情况,您应该从 ID 列中删除 Identity。如果您的意思是,删除第三个项目后,被删除的项目仍然呈现在网页中,可能是删除失败或您没有获取最新数据,请检查List操作方法。
  • @ZhiLv 你首先说的是我的问题,我将如何从 ID 列中删除身份?
  • 嗨@TaricDF,请查看我的回复以从 ID 列中删除身份,如果对我的回复有任何疑问,请随时告诉我。

标签: c# asp.net-mvc asp.net-core razor


【解决方案1】:

SQL 服务器不会重复使用 IDENTITY 列的值。

来自CREATE TABLE (Transact-SQL) IDENTITY (Property)

值的重用 - 对于具有特定种子/增量的给定身份属性,引擎不会重用身份值。如果特定的插入语句失败或插入语句回滚,则使用的标识值将丢失并且不会再次生成。这可能会导致生成后续标识值时出现间隙。

【讨论】:

    【解决方案2】:

    如果您使用 Microsoft Access 作为后端。 自动编号类型可以是“按增量”或“按随机”。 我相信您将列中的值设置为自动编号类型。即使您删除了表格中的某些数据,表格上的自动编号类型也会始终递增。

    另一种解决方案是,您将创建另一个提供 ID(例如 ProductID)的表,该表不是自动增量类型,可能是 text 或其他东西。正如查理所说,自动递增 ids 不会在删除时递减。

    如果您使用 Sql,只需删除主键上的 AUTO_INCREMENT 关键字(如果您将 id 设置为主键)。

    您可能想访问与您的问题相关的帖子:Auto Increment after delete in MySQL

    【讨论】:

    • 在哪里可以找到关键字?
    【解决方案3】:

    为什么当我从数据库中删除时,id 仍然存在?

    正如tymtam所说,对于Identity列,如果delete或insert失败,identity值不会被复用。

    为防止这种行为,在定义模型时,可以使用 Data Annotations 或 Fluent API 指定 ID 属性的值不会由底层数据库生成。

    使用Data Annotations方法,代码如下:

    public class Product
    {
        // using System.ComponentModel.DataAnnotations;
        // using System.ComponentModel.DataAnnotations.Schema;
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int ID { get; set; }
        public string Name { get; set; }
        public DateTime RelaseDate { get; set; }
    }
    

    使用 Fluent API,代码如下:

    public class Product
    {
        // using System.ComponentModel.DataAnnotations; 
        [Key] 
        public int ID { get; set; }
        public string Name { get; set; }
        public DateTime RelaseDate { get; set; }
    }
    

    public class ApplicationDbContext : IdentityDbContext
    { 
        public DbSet<Product> Products { get; set; }
    
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder); 
            builder.Entity<Product>().Property(p => p.ID).ValueGeneratedNever();
        }
    }
    

    然后,使用EF core Migration 生成表格。使用此方法不会自动生成 ID 主键,您必须在插入新产品之前设置其值。

    如果你已经生成了带有Identity列的表,通过上述方法更改属性,迁移时会显示To change the IDENTITY property of a column, the column needs to be dropped and re-created.错误。在这种情况下,您必须从数据库中删除表并删除迁移历史,然后使用上述方法重新生成表。

    另外还有一个解决办法,可以通过SSMS更换表格设计器。

    点击VS2019中的View菜单,选择SQL Server Object Explorer,连接数据库,右键表选择View Designer,然后,在表 T-SQL 面板中,从标识列中删除 Identity(1,1),单击 更新 按钮以保存更改。之后,您可以使用自定义值插入一个新项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多