是否有一种方法可以预先知道通过InsertOnSubmit
插入的记录的标识列的ID,例如在调用datasource的SubmitChanges
?
想象一下,我在数据库中填充某种层次结构,但我不想在每个子节点的每次递归调用上提交更改(例如,如果我有Directories表和Files表,并且我正在重新创建我的文件系统结构数据库)。
我想这样做,所以我创建了一个Directory对象,设置了它的名称和属性,
然后InsertOnSubmit
进入DataContext.Directories集合,然后引用其子文件中的Directory.ID。目前,我需要调用InsertOnSubmit将'directory'插入数据库,数据库映射填充其ID列。但这会创建大量的事务和对数据库的访问,我想如果我这样插入批处理,性能会更好。
我想做的是在提交更改之前以某种方式使用Directory.ID,提前创建我的所有文件和目录对象,然后进行大量提交,将所有内容放入数据库。我也愿意通过存储过程解决这个问题,我认为如果所有操作都直接在数据库中完成,性能会更好。
答案 0 :(得分:3)
解决此问题的一种方法是不使用标识列。而是构建一个IdService,您可以在代码中使用它来在每次创建Directory对象时获取新的Id。
您可以通过使用存储上次使用的ID的表来实现IdService。当服务启动时,它会获取该号码。然后,在创建Directory对象时,服务可以逐渐增加,然后使用在运行结束时使用的新的最后一个id更新表。 或者,更安全一点,当服务启动时,它会获取最后使用的id,然后通过添加1000(例如)来更新表中使用的最后一个id。然后让它增加。如果它使用1000个ID,那么让它抓住下一个1000并更新最后一个id使用表。最糟糕的情况是你浪费了一些id,但如果你使用bigint,你就不会去关心。
由于目录ID现在在代码中受到控制,因此您可以在写入数据库之前将其与子对象(如“文件”)一起使用。
简单地锁定id获取可以安全地跨多个线程使用。我一直在像你这样的情况下使用它。我们在多个线程的内存中生成了大量的对象,并将它们分批保存。
This blog post将为您在Linq to SQL中保存批次提供良好的开端。
答案 1 :(得分:1)
如果有办法在LINQ中运行直接SQL查询,则不确定顶部,但此查询将返回指定表的当前标识值。
USE [database];
GO
DBCC CHECKIDENT ("schema.table", NORESEED);
GO