由于自动生成的问题,正在替换 SQL 服务器标识

Replacing SQL Server IDENTITY Due to Autogenerated Issue

我有一个包含 ID IDENTITY 的发票数据库,每次 LINQ 插入创建新记录时,SQL 服务器自动生成一个 (+1) 的增量。

我目前用来创建新记录的代码发布在下面,增量 ID 由 SQL 服务器自动生成。

public async Task<IActionResult> Create([Bind(
                "PurchaseOrder,InvDate,DelDate,PaidDate,AgentName,FullName,FirstName, LastName,CustId,CompanyName,ClientRole,Email,Phone,Address," +
            "City,State,Zip,Country,ProdCode,Description,Quantity,UnitPrice,LineTotal,OrderTotal,Tax,Discount,Credit," +
            "Shipping,GrandTotal,Deposit,AmtDue,DiscAmt,Notes,Published,Year,Expenses,ProjectDescription,ClientProvision")]
            CreateNewOrderViewModel cnq)
        {
            int invId;

            try
            {
                await _context.AddAsync(cnq);
                await _context.SaveChangesAsync();
            }
            catch (InvalidCastException e)
            {
                ViewBag.Result = $"Database insert failed with: {e}";
                return View();
            }

        }

我的问题是 SQL 服务器 ID IDENTITY。每次重新启动服务器时,我的 ID IDENTITY 值都会增加 1000 倍而不是默认值 1,例如,changes/increases 我创建的下一条记录增加 1000 倍。因此,如果我上一条记录是 1001,则创建的下一条记录将是 2001,而不是 1002。每次更新服务器并需要重新启动时,此行为都会继续。我搜索了一个答案,发现问题是 SQL 服务器错误,它基于记住最新 ID 值的缓存协议。

由于我在共享主机服务器上并且无法完全控制数据库,所以我只有自己的数据库的 DBO。我想知道是否有一种方法可以让我使用 LINQ 为新的 InvID 列生成增量值,然后我可以将其用作记录 ID,而不是 SQL 服务器生成的值。

如果您无法控制数据库来处理 sql server identity gap issue,您需要手动从 table 中读取最大的 Id 并将其递增 1为新记录。
检索最后一个 Id 的示例代码:

int lastId = _context.TableA.OrderByDescending(t => t.Id).FirstOrDefault().Id;
int newId = lastId + 1;
// Add the new record with newId

阅读了几项建议后,我决定在 运行 LINQ 查询之前检查并重新设定 ID。

        using (var connection = new SqlConnection(_data.DATA))
        {
            connection.Open();

            try
            {
                var seed = new SqlCommand("CreateIDSeed", connection)
                {
                    CommandType = CommandType.StoredProcedure
                };
                seed.ExecuteNonQuery();

                await _context.AddAsync(cnq);
                await _context.SaveChangesAsync();
            }
            catch (InvalidCastException e)
            {
                ViewBag.Result = $"Database insert failed with: {e}";
                return View();
            }
        }

CreateIDSeed 看起来像这样:

CREATE PROCEDURE [dbo].[CreateIDSeed] 
AS
BEGIN
    SET NOCOUNT ON;
        declare @newId int
        select @newId = max(ID) from dbo.CreateNewOrderViewModel
        DBCC CheckIdent('dbo.CreateNewOrderViewModel', RESEED, @newId)  
END
GO

我试过插入几条测试记录,好像还可以,但是重启服务器后我会知道更多。