在我们的数据库中,我们有一个缺少标识列的表。有一个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();
答案 0 :(得分:2)
您是否考虑过以下内容:
SELECT
min(RN) AS FirstAvailableID
FROM (
SELECT
row_number() OVER (ORDER BY Id) AS RN,
Id
FROM
YourTable
) x
WHERE
RN <> Id
答案 1 :(得分:1)
回答您如何获得可用号码列表的隐含问题:轻松,列出所有可能的号码,然后删除正在使用的号码。
Source:
以下是通过实体框架
的方法--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