我有一个应用程序(ASP.NET 3.5),允许用户在需要时重新运行特定进程。该过程将记录插入到MS SQL表中。我在Try / Catch中有插入并且如果记录已经存在则忽略catch(Title中的错误将是有效的)。这完全使用ADO,但在我转发到LINQ后,我发现了一件有趣的事情。如果重新运行该过程,表中已有记录,即使没有现有记录,任何新记录也会被拒绝并出现相同的错误。 代码如下:
Dim ins = New tblOutstandingCompletion
With ins
.ControlID = rec.ControlID
.PersonID = rec.peopleID
.RequiredDate = rec.NextDue
.RiskNumber = 0
.recordType = "PC"
.TreatmentID = 0
End With
Try
ldb.tblOutstandingCompletions.InsertOnSubmit(ins)
ldb.SubmitChanges()
Catch ex As Exception
' An attempt to load a duplicate record will fail
End Try
数据库的DataContext是在Page Load。
期间设置的我通过在每次插入之前重新定义DataContext来解决问题:
ldb = New CaRMSDataContext(sessionHandler.connection.ToString)
Dim ins = New tblOutstandingCompletion
虽然我已经解决了这个问题但我想知道是否有人可以解释它。如果没有DataContext重新定义,如果没有重复记录,应用程序将完美运行。
此致 詹姆斯
答案 0 :(得分:2)
我在代码中看到一个非常类似的问题,标识列不是自动增量的int列,而是一个默认值为newguid()的GUID - 基本上LINQ不允许数据库创建GUID,但是插入Guid.Empty,第二次(或稍后)尝试会(正确地)抛出此错误。
我最终确保在插入过程中自己生成了一个新的GUID。更多细节可以在这里看到:http://www.doodle.co.uk/Blogs/2007/09/18/playing-with-linq-in-winforms.aspx
这允许我使用相同的DataContext插入多个记录。
另外,您是否尝试多次调用InsertOnSubmit(每个新记录一次)但只调用SubmitChanges一次?
答案 1 :(得分:1)
听起来DataContext认为记录是第一次插入的,所以如果不重新定义上下文,它会拒绝第二次插入,因为它“知道”记录已经存在。重新定义上下文会强制它实际检查数据库以查看它是否存在,而不是。这是LINQ试图保存到数据库的往返。正如您所做的那样创建新的上下文会强制它重置它“知道”数据库的内容。
答案 2 :(得分:1)
gfrizzle似乎就在这里......
我的代码因重复键错误而失败,即使我只是运行存储过程来截断数据库上的表。就数据上下文所知,先前使用相同键插入记录实际上是一个重复键,并抛出异常。
我发现的唯一方法是:
db = null;
db = new NNetDataContext();
在执行先前的InsertOnSubmit请求的SubmitChanges()调用之后。看起来有点愚蠢,但除了重新设计代码之外,它是唯一适合我的方式。