我在SQL Server数据库中有一个表,我想添加一行。主键不是自动增量,我不希望它。但是,在这个场合,我确实希望添加一个具有下一个可用值的行。有一个简单的方法吗?我知道我可以查询表中的最大值然后递增它但是使用EF时有更简单的方法吗?
如果需要单独的查询获取MAX值,您将如何使用LINQ执行此操作?
答案 0 :(得分:5)
除非服务器是身份或计算列,否则将是必要的,在这种情况下,您可以执行以下操作。
myRecord.ID = Context.Records.Max(record => record.ID) + 1;
答案 1 :(得分:2)
没有简单的方法,特别是如果你坚持下一个可用值(=无间隙)。您应该使用自动增量值,它将使您的应用程序执行得更好。
有什么问题?
看起来很简单,不是吗?不,如果您有并发环境,其中多个线程可以在其他线程到达步骤3之前同时执行步骤1. =所有线程将插入具有相同值的记录。
如何处理?一种方法是使用具有最大值和原子操作的单独表来获取和增加该值。我认为存储过程做这样的事情应该是原子的:
DECLARE @Result INT
UPDATE SequenceTable SET @Result = MaxValue = MaxValue + 1 WHERE SequnceName = '...'
RETURN @Result
对存储过程的调用应该在任何事务之外,以获得最佳吞吐量。
这应该允许您生成唯一的数字,但不能无间隙地进行排序。如果您通过此类操作获取该值并且您不会使用该值,则它将丢失并且您的序列将包含间隙。
如果您不想要间隙,则必须将存储过程调用和操作放入事务中,以便锁定序列表中的记录,直到提交数据为止。