C#WPF使用datagrid从数据库中删除带有主键的项目

Posted

技术标签:

【中文标题】C#WPF使用datagrid从数据库中删除带有主键的项目【英文标题】:C# WPF delete item with its primary key from database using datagrid 【发布时间】:2016-03-10 11:19:16 【问题描述】:

使用 LINQ,我正在尝试使用 db.Dishes.Remove(Dish); 从数据库中删除数据网格中的选定行(首先使用代码制作)

但是当我删除该项目并插入一个新项目时,新项目的主键 (id) 会“跳转”一个值。

例如

1 Shoes
2 Jeans   //I delete this item

添加新项目时

1 Shoes
3 T-Shirt    //jumps a value for Id

我在DBContext.cs 中也尝试过这个

modelBuilder.Entity<Cart>()
            .HasOptional(i => i.Item)
            .WithMany()
            .WillCascadeOnDelete(true);

但它不起作用

有没有更好的方法从数据库中删除项目?

【问题讨论】:

您的主键设置为身份,这就是它跳跃的原因。如果您不需要数据库中的识别列,那么建议您根据功能需求制作主键并通过应用程序进行管理。 @user1672994 好的,但是我需要我的主键来生成数据库。即使我删除身份设置,这是否可能? 【参考方案1】:

问题是,当我们使用 DELETE 时,它会从表中删除行但计数器不会更改(如果删除的行具有自动增量 PK)请参阅 DELETE vs TRUNCATE . 因此,如果您想重用键值,那么您可以执行以下操作:

1) 在代码中处理 Key 的 Auto Increment 部分

2) 如果你有 访问数据库或想要查询它的内容 可能会有所帮助(SQL Server):

DBCC CHECKIDENT ('tablename', RESEED, newseed)

从代码中执行此操作,您可以在删除后执行:

db.ExecuteCommand("DBCC CHECKIDENT('tablename', RESEED, newseed);")

其中 'newseed' 是已删除行的 id。例如,如果 newseed 为 0,则下一个插入将为 1,如果为 10,则插入将为 11。要获得新的种子值,您还可以获得驻留在您的数据库中的最大 id 值,然后从那里开始工作。如果您决定走这条路,最好看看您可以采取哪些方法。

来自Reset autoicrement in SQL Server 以及如何在code 中使用它。

【讨论】:

你的回答很有用。我在哪里可以做到这一点,因为我首先使用代码?【参考方案2】:

主键必须是唯一的(根据定义),并且您还将其定义为标识列。

因此,当您删除一行并创建一个新行时,该新行将采用 next 可用键(在您的情况下为 3)。

如果您不希望这种行为,您将不得不自己管理主键的唯一性。

【讨论】:

好的,很清楚。谢谢你。顺便说一句,我更喜欢数据库生成的值,因为它是一个非常简单的应用程序。【参考方案3】:

如果您的主键是自动整数,则无法避免这种行为。这就是数据库的工作原理。如果要控制 int 值,请不要将其作为主键,也不要使用自动整数。而是使用 uniqueidentifier 作为您的主键,并使您的 int 成为普通字段。然后,当您创建新记录时,您需要有一个强大的机制来获取下一个索引,锁定它以便其他人无法窃取它,然后写入您的记录。

这在多线程环境中可不是小事!您应该对该主题进行一些研究并提出一个好的方案。就个人而言,我永远不会尝试这样做,而是会使用可重复的过程来生成非连续的或线程独有的数字。

【讨论】:

以上是关于C#WPF使用datagrid从数据库中删除带有主键的项目的主要内容,如果未能解决你的问题,请参考以下文章

读取自定义Datagrid的每个单元格数据 - WPF C#

C# WPF Datagrid:从 SelectionChanged 事件中获取值

WPF中对datagrid删除选中的某一行。

WPF DataGrid 如何对选择的多行进行删除

将datagrid WPF绑定到带有列表的两个不同类?

删除 WPF DataGrid 中的空白列