我第一次使用LINQ而且我遇到了一些我不完全理解DataContext的行为。希望StackOverflow可以提供帮助。
基本上,似乎一旦我的DataContext遇到异常,它就会缓存该异常或永远不会完全恢复。在我的特定情况下,一旦我尝试传递一个对我的数据库来说太大的字符串,它会为所有后续字符串抛出相同的异常。
我有一张桌子:
DisplayString(
StringID nvarchar(255)
,CultureCode varchar(25)
,DisplayString nvarchar(255)
)
在.Net中我创建了一个DataContext,我使用LINQ to SQL类映射到该表。
Dim context As New LinqTableMappingDataContext(
My.Settings.LocalizationStringsConnectionString)
然后我创建了一堆测试字符串,遍历每个测试字符串并将它们发送到我的表格。
Dim arr As String() =
{"aaaaa", "adsfs", "wefwf", "dfgsfg", "ergsdfg",
"fsdgergd", "Sdgdfgegd", "ergdfgsfd"}
For Each a As String In arr
addToLinq(a)
Next
这很好用。但是,如果我在索引1处添加以下字符串,则所有后续插入失败,抛出与长字符串相同的异常(SqlException)。
"WARNING: This computer program is protected by copyright law and international
treaties. Unauthorized reproduction of this program, or any portion of it, may
result in severe civil and criminal penalties, and will be prosecuted to the
maximum extent possible under the law."
这是我的AddToLinq()方法。
Private Sub AddToLinq(ByVal stringID As String)
Dim f As New DisplayString
Try
Dim count As Integer = (From str In context.DisplayStrings _
Where str.StringID = stringID Select str).Count
If count = 0 Then
f.StringID = stringID
f.CultureCode = "en-US"
f.DisplayString = stringID
context.DisplayStrings.InsertOnSubmit(f)
context.SubmitChanges()
Console.WriteLine("SUBMITTED: " & stringID)
End If
Catch ex1 As SqlException
Console.WriteLine("------------------------------------------------")
Console.WriteLine("EXCEPTION: " & ex1.Message)
Console.WriteLine(stringID)
Console.WriteLine(stringID.Length)
Console.WriteLine("------------------------------------------------")
Catch ex As DuplicateKeyException
Console.WriteLine(ex.Message)
End Try
End Sub
如果有人能帮助我那会很棒,谢谢。
答案 0 :(得分:2)
如果你观察到DataContext的GetChangeSet method,你会发现它仍然想要插入第一个字符串。这就是它无法恢复的原因。
答案 1 :(得分:1)
每次需要时创建一个新的上下文,而不是重用全局/静态上下文成员。问题是您的上下文对象处于错误状态。
....
if (count = 0)
Dim context As New [Your context here]
....
end if
答案 2 :(得分:0)
它实际上是在同一个插件上失败,因为您没有从数据上下文中删除失败的字符串,并且每次调用SubmitChanges时它都会尝试插入它。正如@confusedGeek建议你可以通过为每个插入实例化一个新的数据上下文来解决这个问题。或者,您可以将ConflictMode设置为ContinueOnConflict,我相信其余的更改将被插入。由于您要在每次添加时提交更改,我会选择使用前一个解决方案并为每个插入创建单独的上下文。
编辑:另一种选择是让你的异常处理程序处理旧的上下文并在出错时创建一个新的上下文。我不确定这是一个多大的改进 - 似乎比必要的复杂一点。数据上下文是非常轻量级的实体,所以我不会太在意根据需要创建一个新实体。