Sql server 不带标识列的LINQ插入
我使用的是LINQ,但我的数据库表没有标识列(尽管它们使用的是代理主键ID列) 这行吗 要获取表的标识值,有一个名为GetIDValueForOrangeTable()的存储过程,它查看SystemValues表并递增其中的ID。 有没有办法让LINQ在insert上从这个SystemValues表中获取ID值,而不是内置标识 顺便说一句,我认为这不是一个好主意,尤其是对于web应用程序。我想由于这个SystemValues查找,会有很多并发冲突。我的担心有道理吗 干杯Sql server 不带标识列的LINQ插入,sql-server,linq-to-sql,identity-column,Sql Server,Linq To Sql,Identity Column,我使用的是LINQ,但我的数据库表没有标识列(尽管它们使用的是代理主键ID列) 这行吗 要获取表的标识值,有一个名为GetIDValueForOrangeTable()的存储过程,它查看SystemValues表并递增其中的ID。 有没有办法让LINQ在insert上从这个SystemValues表中获取ID值,而不是内置标识 顺便说一句,我认为这不是一个好主意,尤其是对于web应用程序。我想由于这个SystemValues查找,会有很多并发冲突。我的担心有道理吗 干杯 Duncan确保您可以使
Duncan确保您可以使用LINQ安全地完成此任务:
- 将对底层SystemValues表的访问权包装在事务中的“GetIDValue…”函数中(而不是使用READUNCOMMITTED隔离级别!),然后在任何给定时间只有一个用户可以访问该表,您应该能够安全地分发ID
- 在保存实体之前从LINQ调用该存储过程,如果您正在处理新实体(如果尚未设置ID),则存储ID
- 将实体存储在数据库中
CREATE PROCEDURE dbo.GetNextTableID(@TableID INT OUTPUT)
AS BEGIN
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
BEGIN TRANSACTION
UPDATE SystemTables
SET MaxTableID = MaxTableID + 1
WHERE ........
SELECT
@TableID = MaxTableID
FROM
dbo.SystemTables
COMMIT TRANSACTION
END
至于性能-只要您有合理数量的并发用户(可能少于50个),并且只要这个
SystemTables
表不用于其他用途,那么它的性能应该是正常的。您的担心是非常合理的。如果两个用户试图在同一时间插入,则两个用户可能会得到相同的号码,除非您按照marc_s的描述进行操作,并将其放入事务中。但是,如果事务没有围绕您的整个插入以及包含id值的表进行包装,那么如果外部插入失败,您可能仍然会有间隙(它获得了一个值,但由于其他原因没有插入记录)。由于大多数人这样做是为了避免差距(在大多数情况下,这是一项不必要的要求),这使得生活更加复杂,仍然可能无法实现结果。使用身份字段几乎总是一个更好的选择。但在web应用程序中这是否安全(且性能合理)?web唯一有效的事务级别是乐观锁定,不是吗?如果我错了,请纠正我!非常感谢,非常感谢,我会考虑一下。然而,我们可能会有成千上万的用户在短时间内访问这个数据库,所以我们必须认真考虑性能!您无需访问SystemTables
两次即可执行此操作,就像第二种方法一样