C# 使用Linq-2-SQL插入和更新
只要我坚持只读操作,L2SQL看起来就很棒。一旦我需要开始改变领域,事情就会变得有点棘手 特别是,我遇到了两个截然不同的问题 首先,我试图用任意数量的行填充一个表。模式基本上是不相关的,但它有一个“BIGINT”主键,即identity列 由于主键是一个标识,因此在调用Table.InsertOnSubmit()或Table.InsertAllOnSubmit()之前,我不会对其进行设置,并且会产生DuplicateKeyException:“无法添加具有已在使用的键的实体。” 我的第二个担忧源于需要与以下SQL语句等效的LINQ:C# 使用Linq-2-SQL插入和更新,c#,asp.net,linq-to-sql,C#,Asp.net,Linq To Sql,只要我坚持只读操作,L2SQL看起来就很棒。一旦我需要开始改变领域,事情就会变得有点棘手 特别是,我遇到了两个截然不同的问题 首先,我试图用任意数量的行填充一个表。模式基本上是不相关的,但它有一个“BIGINT”主键,即identity列 由于主键是一个标识,因此在调用Table.InsertOnSubmit()或Table.InsertAllOnSubmit()之前,我不会对其进行设置,并且会产生DuplicateKeyException:“无法添加具有已在使用的键的实体。” 我的第二个担忧源
UPDATE dbo.someTable SET someCol = 'someValue' WHERE pkValue = 20
如果我先查询所需的行,然后在DataContext.SubmitChanges()之前更改someCol的值,一切都可以。
但是,我正在寻找一种不需要我首先查询行的解决方案。换句话说,如果主键是一个已知的量,那么如何执行呢?看看Jose指出的问题,我从中得到的是,当人们尝试插入同一个对象两次时,会出现错误(这很有意义-第一次插入将锁定ID,第二次更新将插入刚刚创建的ID);是否可能在提交时为同一对象标记两次(或更多次)以进行插入?您说您正在插入“任意数量的行”-为什么不尝试将其降到一行 本质上,Linq to SQL应该在您谈论它时处理这种情况—标识列不应该填充该值,您可以调用InsertOnSubmit()并提交更改以将其包含在内
至于你的第二个问题,我认为Linq to SQL没有任何明确的方式来做你想要做的事情。可能最简单/最好的解决方案是有一个存储过程来更新你想要的数据,并使用Linq to SQL调用它(传递你想要更新的记录ID)。对于你的第一个问题:你的PK是否自动递增DB 对于您的第二个问题,如果理解正确,以下内容应该会有所帮助(摘自L2S上的MSDN常见问题解答)。您应该测试以下内容,因为我对MSDN有不好的体验;-): Q.我是否可以在没有数据的情况下更新表数据 首先查询数据库 A.虽然LINQ到SQL没有 基于集合的更新命令,可以使用 使用以下技术之一 无需首先查询即可更新: 使用ExecuteCommand发送SQL代码 创建对象的新实例 并初始化所有当前值 影响更新的(字段)。然后 将对象附加到DataContext 通过使用“附加并修改”字段 你想要改变
请注意:对于不进行查询的更新,您必须确保DataContext没有加载相同的对象。我已经找到了问题的答案 首先,我的重复键问题是由于我的表被设计器导入得不好造成的。我从服务器资源管理器中删除了连接,从头开始,解决了这个问题 其次,我确定以下代码示例解决了我的第二个问题:
using( var dc = new MyDataContext() )
{
TableValue row = new TableValue();
row.pkValue = 20;
dc.TableValues.Attach(row); // DataContext thinks 'row' is the original.
row.someCol = "Changed Value"; // DataContext formats an UPDATE statement
dc.SubmitChanges();
}
DataContext.someTable.Where(a => a.pkValue == 20).SingleOrDefault().someCol = 'someValue';
DataContext.SubmitChanges();
需要注意的是,我必须将所有表列的“更新检查”属性设置为“从不”,否则会引发异常。这让我觉得有点不舒服,并让我相信这不是最好的解决方案,但这可能部分是因为我不了解“更新检查”属性的实际用途。关于您的第二个问题:
using( var dc = new MyDataContext() )
{
TableValue row = new TableValue();
row.pkValue = 20;
dc.TableValues.Attach(row); // DataContext thinks 'row' is the original.
row.someCol = "Changed Value"; // DataContext formats an UPDATE statement
dc.SubmitChanges();
}
DataContext.someTable.Where(a => a.pkValue == 20).SingleOrDefault().someCol = 'someValue';
DataContext.SubmitChanges();
你在第二部分很可能是对的。遗憾的是,我对SPROCs知之甚少,但在我能够考虑这个解决方案之前,我必须学会自己。