![](/img/trans.png)
[英]How to keep ID from increasing and use first available unused ID instead?
[英]Getting the first unused Id from a table?
在我们的数据库中,我们有一个缺少标识列的表。 有一个Id列,但在输入记录时会手动填充。 Id超过90,000的所有项目都将保留并在所有客户数据库中全局填充。
我正在构建一个使用Entity Framework处理向此表中批量插入的工具。 我需要找出在没有迭代每一行的情况下即时找到第一个可用ID的最有效方法(小于90,000)。 在许多数据库中,很可能有人只是选择了一个未被使用的随机数,然后使用它来插入行。
我最好的办法是什么?
在看到列出的一些解决方案之后,我尝试在Linq中复制SQL逻辑。 我怀疑它是完美的,但它似乎是快速和高效的。
var availableIds = Enumerable.Range(1, 89999)
.Except(db.Table.Where(n => n.Id <= 89999)
.Select(n => n.TagAssociationTypeID))
.ToList();
您是否考虑过类似的东西:
SELECT
min(RN) AS FirstAvailableID
FROM (
SELECT
row_number() OVER (ORDER BY Id) AS RN,
Id
FROM
YourTable
) x
WHERE
RN <> Id
要回答有关如何获取可用数字列表的隐式问题:轻松,列出所有可能的数字,然后删除正在使用的数字。
--This builds a list of numbers from 1 to 89999
SELECT TOP (89999) n = CONVERT(INT, ROW_NUMBER() OVER (ORDER BY s1.[object_id]))
INTO #AvialableNumbers
FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2
OPTION (MAXDOP 1);
CREATE UNIQUE CLUSTERED INDEX n ON #AvialableNumbers(n)
--Start a seralizeable transaction so we can be sure no one uses a number
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
begin transaction
--Remove numbers that are in use.
delete #AvialableNumbers where n in (select Id from YourTable)
/*
Do your insert here using numbers from #AvialableNumbers
*/
commit transaction
这是您通过实体框架执行的操作
using(var context = new YourContext(connectionString))
using(var transaction = context.Database.BeginTransaction(IsolationLevel.Serializable))
{
var query = @"
SELECT TOP (89999) n = CONVERT(INT, ROW_NUMBER() OVER (ORDER BY s1.[object_id]))
INTO #AvialableNumbers
FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2
OPTION (MAXDOP 1);
CREATE UNIQUE CLUSTERED INDEX n ON #AvialableNumbers(n)
--Remove numbers that are in use.
delete #AvialableNumbers where n in (select Id from YourTable)
--Select the numbers out to the result set.
select n from #AvialableNumbers order by n
drop table #AvialableNumbers
";
List<int> availableIDs = context.Database.SqlQuery<int>(query).ToList();
/*
Use the list of IDs here
*/
context.SaveChanges();
transaction.Commit();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.