Linq To Sql和identity_insert
我试图在主键是Identity
字段的表上进行记录插入。
我试过打电话
mycontext.ExecuteCommand("SET identity_insert myTable ON")
但这没有任何好处。
当我提交更改时,我收到一条错误,提示IDENTITY_INSERT
为OFF
。
在提交更改之前,如何从C#代码打开它?
编辑
我已经读过这是因为ExecuteCommand的代码在不同的会话中执行。
编辑2
有没有什么办法可以执行一些DDL来从我的C#代码中删除身份规范,进行插入,然后重新打开身份规范?
您需要在单个T-SQL代码块中执行所有步骤 – 如果您想打开它,那么这将非常困难,然后执行您的LINQ-to-SQL查询,然后将其关闭:(
我看到的唯一真正的解决方案是将整个SQL打包成SQL语句并执行:
SET IDENTITY_INSERT MyTable ON (do your update here) SET IDENTITY_INSERT MyTable OFF
并使用.ExecuteContext()
其作为单个代码块执行
渣
PS:对于你的编辑#2:不,不幸的是,没有(简单的)方法从列中删除标识,并将其重新打开。 Basicall你必须创建一个没有IDENTITY的新列,复制值,删除IDENTITY列,然后在完成时向后执行相同操作 – 抱歉! 🙁
PS#2:这真的引出了一个问题:到底要做什么需要做一个“身份插入”? 从应用程序定期? 当然 – 你可能会偶尔遇到这种需求,但我总是在SQL Mgmt Studio中单独执行此操作 – 当然不在我的应用程序中…..(只是好奇你的用例/动机是什么)。
另一种选择是将所有Linq2Sql调用包装在TransactionScope()中。 这应该强制它们在同一个连接中运行。
using System.Transactions; // Be sure to add a reference to System.Transactions.dll to your project. // ... in a method somewhere ... using (System.Transaction.TransactionScope trans = new TransactionScope()) { using(YourDataContext context = new YourDataContext()) { context.ExecuteCommand("SET IDENTITY_INSERT MyTable ON"); context.ExecuteCommand("yourInsertCommand"); context.ExecuteCommand("SET IDENTITY_INSERT MyTable OFF"); } trans.Complete(); } // ...
虽然,如果你想尝试做类似的事情:
context.ExecuteCommand("SET IDENTITY_INSERT MyTable ON"); context.MyTable.InsertOnSubmit(myTableObject) context.SubmitChanges() context.ExecuteCommand("SET IDENTITY_INSERT MyTable OFF");
您可能会遇到其他问题,尤其是在标识列将IsDbGenerated属性设置为true的情况下。 Linq2Sql生成的SQL命令不知道包含标识列和值。
在执行命令之前,应该足以手动打开连接。 这使得命令在同一会话中运行:
context.Connection.Open(); context.ExecuteCommand("SET IDENTITY_INSERT MyTable ON"); // make changes // ... context.SubmitChanges();
我做的是这样的(Nbuider用于创建实体)。 我通常创建除了标识插入行之外的所有行; 这最终完成了。 这是测试数据创建,因此不需要事务。
using (var entitiesEfContext = new ContextABC()) { var platforms = Builder .CreateListOfSize(4) .TheFirst(1) .With(x => x.Description = "Desc1") .With(x => x.IsDeleted = false) .TheNext(1) .With(x => x.Description = "Desc2") .With(x => x.IsDeleted = false) .TheNext(1) .With(x => x.Description = "Desc3") .With(x => x.IsDeleted = false) .TheNext(1) .With(x => x.Description = "Desc4") .With(x => x.IsDeleted = false) .Build(); foreach (var platform in platforms) { entitiesEfContext.Platform.AddObject(platform); } entitiesEfContext.SaveChanges(); // the identity insert row (o as id in my case) entitiesEfContext.ExecuteStoreCommand("SET IDENTITY_INSERT Platform ON; INSERT INTO [Platform](Platformid,[Description],[IsDeleted],[Created],[Updated]) VALUES (0,'Desc0' ,0 ,getutcdate(),getutcdate());SET IDENTITY_INSERT Platform Off"); }
我有相同的错误消息。 我通过更改表中主键的属性来解决它。
MyTable.MyId int IDENTITY(1,1) NOT NULL
属性设置MyId(在dbml中 )
- 自动生成值: 正确 ;
- 自动同步: OnInsert ;
- 主键: 正确 ;
- 服务器数据类型: int NOT NULL IDENTITY ;
- 输入: int ;
每次添加新记录时,只需简单的reseed identity key
(带自定义ID),例如:
using (var desDb = new DesDbContext()) { // del-table-all -------------------------------------------------------- desDb.Database.ExecuteSqlCommand("DELETE FROM [Products]"); foreach (var desItem in desList) //desList is List of Product { // reseed identity key desDb.Database.ExecuteSqlCommand("DBCC CHECKIDENT('Products', RESEED," + (desItem.ProductID - 1) + ");"); // and record desDb.Products.Add(desItem); // save-db desDb.SaveChanges(); } }
- HttpClient不能正确序列化XML
- 没有明确的ServicePointManager.SecurityProtocol调用,在.NET 4.7中没有协商TLS 1.2
- 如何在WinForms项目中将XML用作DataGridView的DataSource?
- IronRuby在.NET 3.5中调用C#扩展方法 – 错误 – 兼容性
- .Net Core 2.1 – 无法访问已处置的对象。对象名称:’IServiceProvider’
- 如何在完成之前从ReplaySubject 获取最新值
- 使用WPF数据网格时如何更改列标题的背景颜色
- MEF CachedAssemblyCatalog – 延迟加载程序集
- 如何加密密码以便以后将其保存在数据库或文本文件中?