有没有办法事先知道通过 InsertOnSubmit
插入的记录的标识列的 ID,例如在调用数据源的 SubmitChanges
之前?
假设我在数据库中填充某种层次结构,但我不想在每个子节点的每次递归调用上提交更改(例如,如果我有目录表和文件表,并且正在重新创建我的文件系统结构数据库)。
我想那样做,所以我创建了一个 Directory 对象,设置了它的名称和属性,
然后 InsertOnSubmit
将其放入 DataContext.Directories 集合,然后 在其子文件中引用 Directory.ID。目前我需要调用 InsertOnSubmit 将“目录”插入数据库,并且数据库映射填充它的 ID 列。但这会创建大量事务和对数据库的访问,我想如果我批量插入,性能会更好。
我想做的是在提交更改之前以某种方式使用 Directory.ID,提前创建我所有的文件和目录对象,然后进行一次大提交,将所有内容放入数据库。我也愿意通过存储过程解决这个问题,我认为如果所有操作都直接在数据库中完成,性能会更好。
最佳答案
解决这个问题的一种方法是不使用标识列。而是构建一个 IdService,每次创建 Directory 对象时,您都可以在代码中使用它来获取新的 Id。
您可以通过存储最后使用的 ID 的表来实现 IdService。当服务启动时,让它获取该号码。然后,该服务可以在创建 Directory 对象时递增,然后使用运行结束时使用的新的最后一个 ID 更新表。 或者,更安全一点的是,当服务启动时,让它获取最后使用的 ID,然后通过添加 1000(例如)来更新表中使用的最后一个 ID。然后让它递增。如果它使用 1000 个 id,那么让它获取下一个 1000 并更新最后使用的 id 表。最坏的情况是你浪费了一些 id,但如果你使用 bigint,你永远不会在意。
由于目录 ID 现在在代码中控制,您可以在写入数据库之前将其与子对象(如文件)一起使用。
简单地在 id 获取周围加一个锁就可以安全地跨多个线程使用。我一直在像你这样的情况下使用它。我们正在跨多个线程在内存中生成大量对象并分批保存它们。
This blog post将为您在 Linq to SQL 中保存批处理提供一个良好的开端。
关于linq - 在 LINQ 中提交更改之前引用对象的标识,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1875158/