使用LINQ插入含复合主键的表报错,求无拼接文本框值的查询方案
问题解决指南:IDENTITY_INSERT异常+安全查询写法
一、解决“IDENTITY_INSERT为OFF时无法插入标识列值”的异常
首先得明确:这个报错是因为你试图给数据库设置为自增的标识列手动赋值了,而默认情况下IDENTITY_INSERT是关闭的,不允许这么做。结合你的复合主键(stid+bookid),先检查这两个列里哪一个被设置成了自增标识列。
两种解决场景:
不需要手动赋值标识列(常规场景)
如果这个标识列是数据库自动生成的(比如用户ID、记录ID自增),那直接去掉代码里给这个列赋值的语句就行。比如假设stid是自增列,那创建实体时只给bookid和其他字段赋值:using (DataClasses1DataContext dv = new DataClasses1DataContext()) { var newRecord = new YourTableName // 替换成你的实体类名 { // stid = 123, 删掉这行,让数据库自动生成 bookid = int.Parse(bookIdText.Text), // 其他字段赋值... }; dv.YourTableName.InsertOnSubmit(newRecord); dv.SubmitChanges(); }必须手动赋值标识列(比如数据迁移)
如果你确实需要给自增列手动插入值,那就得先开启IDENTITY_INSERT,操作完成后再关闭:using (DataClasses1DataContext dv = new DataClasses1DataContext()) { // 替换成你的实际表名(数据库里的表名,不是实体类名) dv.ExecuteCommand("SET IDENTITY_INSERT YourDatabaseTableName ON"); var newRecord = new YourTableName { stid = 1001, // 手动赋值自增列 bookid = 2001, // 其他字段... }; dv.YourTableName.InsertOnSubmit(newRecord); dv.SubmitChanges(); dv.ExecuteCommand("SET IDENTITY_INSERT YourDatabaseTableName OFF"); }注意:IDENTITY_INSERT一次只能对一个表开启,操作完一定要关闭,避免影响其他操作。
二、避免拼接文本框值的安全查询写法
你担心的拼接bname.Text这类值的问题,本质是要防止SQL注入,同时避免特殊字符导致的语法错误。在Linq to SQL里,直接用变量传值就可以自动实现参数化,完全不需要手动拼接字符串:
正确示例:
Linq查询方式(推荐)
直接把文本框的值存到变量里,然后在Linq表达式里用变量:string targetBookName = bname.Text; // Linq to SQL会自动把targetBookName作为参数传入,不会拼接字符串 var query = from book in dv.Books where book.BookName == targetBookName select book;执行原生SQL的参数化写法
如果需要执行原生SQL语句,用ExecuteCommand时通过占位符传参数,不要手动拼接:string targetBookName = bname.Text; int newStock = 10; // {0}、{1}是占位符,对应后面的参数,自动参数化 dv.ExecuteCommand("UPDATE Books SET Stock = {0} WHERE BookName = {1}", newStock, targetBookName);这样既安全,又不会因为文本框里有单引号这类特殊字符导致SQL语法错误。
内容的提问来源于stack exchange,提问作者HTG
相关产品推荐
相关产品推荐

