Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
引用对象';在提交LINQ中的更改之前,请先验证身份_Linq_Identity - Fatal编程技术网

引用对象';在提交LINQ中的更改之前,请先验证身份

引用对象';在提交LINQ中的更改之前,请先验证身份,linq,identity,Linq,Identity,是否有一种方法可以事先知道通过InsertOnSubmit插入的记录的标识列的ID,例如在调用数据源的提交更改之前 假设我正在数据库中填充某种层次结构,但我不想在每个子节点的每次递归调用上提交更改(例如,如果我有目录表和文件表,并且正在数据库中重新创建文件系统结构) 我想这样做,所以我创建一个目录对象,设置它的名称和属性, 然后将其提交到DataContext.Directories集合中,然后在其子文件中引用Directory.ID。目前,我需要调用InsertOnSubmit将“目录”插入数

是否有一种方法可以事先知道通过
InsertOnSubmit
插入的记录的标识列的ID,例如在调用数据源的
提交更改之前

假设我正在数据库中填充某种层次结构,但我不想在每个子节点的每次递归调用上提交更改(例如,如果我有目录表和文件表,并且正在数据库中重新创建文件系统结构)

我想这样做,所以我创建一个目录对象,设置它的名称和属性, 然后将其提交到DataContext.Directories集合中,然后在其子文件中引用Directory.ID。目前,我需要调用InsertOnSubmit将“目录”插入数据库,数据库映射将填充其ID列。但这会创建很多事务和对数据库的访问,我想如果我在批处理中插入这些事务,性能会更好


我想做的是在提交更改之前以某种方式使用Directory.ID,提前创建我的所有文件和目录对象,然后进行一次大型提交,将所有内容放入数据库。我也愿意通过存储过程来解决这个问题,我认为如果所有操作都直接在数据库中完成,性能会更好。

首先不确定是否有办法在LINQ中运行直接SQL查询,但此查询将返回指定表的当前标识值

USE [database];
GO
DBCC CHECKIDENT ("schema.table", NORESEED);
GO

解决这个问题的一种方法是不使用标识列。而是构建一个IdService,您可以在代码中使用它在每次创建目录对象时获取新Id

您可以通过使用一个存储上次使用的id的表来实现IdService。当服务启动时,让它获取该号码。然后,该服务可以在创建目录对象时递增,然后使用运行结束时使用的新的最后一个id更新表。 或者,更安全一点,当服务启动时,让它获取最后使用的id,然后通过添加1000(例如)更新表中使用的最后一个id。然后让它逐渐消失。如果它使用1000个id,那么让它抓取下一个1000并更新表中最后使用的id。最糟糕的情况是你浪费了一些ID,但如果你使用了bigint,你永远不会在意

由于目录id现在由代码控制,因此在写入数据库之前,您可以将其与子对象(如文件)一起使用

只要在id获取周围加上一个锁,就可以跨多个线程安全地使用它。我在你这种情况下用过这个。我们正在跨多个线程在内存中生成大量对象,并将它们分批保存


这将为您在Linq中将批保存到SQL中提供一个良好的开端。

谢谢,但我可能会在一个批中生成数千条记录,甚至在几个不同的线程上,因此标识列值会混淆。我曾想过关闭自动身份生成功能,但后来我意识到,我可能会同时运行多个这样的查询,我自己无法可靠地生成身份值。是的,一开始我误解了你。我以为你只是一次谈论一个目录对象和很多文件,但实际上你一次想要很多目录和很多文件。