【发布时间】:2010-04-27 18:49:38
【问题描述】:
与其他问题类似的错误,但不完全相同,我没有尝试附加任何内容。
我要做的是在链接表中插入一个新行,特别是 UserAccomplishment。关系在 LINQ 中设置为用户和成就表。
我有一个通用的插入函数:
Public Function insertRow(ByVal entity As ImplementationType) As Boolean
If entity IsNot Nothing Then
Dim lcfdatacontext As New LCFDataContext()
Try
lcfdatacontext.GetTable(Of ImplementationType)().InsertOnSubmit(entity)
lcfdatacontext.SubmitChanges()
lcfdatacontext.Dispose()
Return True
Catch ex As Exception
Return False
End Try
Else
Return False
End If
End Function
如果您尝试为 UserAccomplishment 提供两个适当的对象,如果 User 或 Accomplishment 已经存在,这自然会出错。它仅在用户和成就都不存在时才有效。我预料到了这种行为。起作用的只是简单地给 userAccomplishment 对象一个 user.id 和 completion.id 并填充其余字段。这可行,但在我的应用程序中使用有点尴尬,简单地传入两个对象并让它计算出已经存在的内容和不存在的内容会容易得多。好的,所以我做了以下事情(请忽略这样一个事实,因为我知道这是非常低效的):
Public Class UserAccomplishmentDao
Inherits EntityDao(Of UserAccomplishment)
Public Function insertLinkerObjectRow(ByVal userAccomplishment As UserAccomplishment)
Dim insertSuccess As Boolean = False
If Not userAccomplishment Is Nothing Then
Dim userDao As New UserDao()
Dim accomplishmentDao As New AccomplishmentDao()
Dim user As New User()
Dim accomplishment As New Accomplishment()
'see if either object already exists in db'
user = userDao.getOneByValueOfProperty("Id", userAccomplishment.User.Id)
accomplishment = accomplishmentDao.getOneByValueOfProperty("Id", userAccomplishment.Accomplishment.Id)
If user Is Nothing And accomplishment Is Nothing Then
'neither the user or the accomplishment exist, both are new so insert them both, typical insert'
insertSuccess = Me.insertRow(userAccomplishment)
ElseIf user Is Nothing And Not accomplishment Is Nothing Then
'user is new, accomplishment is not new, so just insert the user, and the relation in userAccomplishment'
Dim userWithExistingAccomplishment As New UserAccomplishment(userAccomplishment.User, userAccomplishment.Accomplishment.Id, userAccomplishment.LastUpdatedBy)
insertSuccess = Me.insertRow(userWithExistingAccomplishment)
ElseIf Not user Is Nothing And accomplishment Is Nothing Then
'user is not new, accomplishment is new, so just insert the accomplishment, and the relation in userAccomplishment'
Dim existingUserWithAccomplishment As New UserAccomplishment(userAccomplishment.UserId, userAccomplishment.Accomplishment, userAccomplishment.LastUpdatedBy)
insertSuccess = Me.insertRow(existingUserWithAccomplishment)
Else
'both are not new, just add the relation'
Dim userAccomplishmentBothExist As New UserAccomplishment(userAccomplishment.User.Id, userAccomplishment.Accomplishment.Id, userAccomplishment.LastUpdatedBy)
insertSuccess = Me.insertRow(userAccomplishmentBothExist)
End If
End If
Return insertSuccess
End Function
End Class
好的,这里我主要检查提供的用户和成就是否已经存在于数据库中,如果存在,则调用适当的构造函数,将已经存在的任何内容留空,但提供其余信息以便插入成功。
但是,在尝试插入时:
Dim result As Boolean = Me.userAccomplishmentDao.insertLinkerObjectRow(userAccomplishment)
用户已经存在,但成就不存在(99% 的典型场景)我得到错误:
"An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported."
我现在已经调试了很多次,但不确定为什么会发生这种情况,如果 User 或 Accomplishment 存在,我不会将它包含在尝试插入的最终对象中。因此,似乎没有尝试添加任何内容。即使在调试中,插入时,对象也被设置为空。所以成就是新的,用户是空的。
1) 为什么它仍然这么说,我该如何修复它..使用我当前的结构
2) 先发制人的“使用存储库模式答案” - 我知道这种方式通常很糟糕,我应该使用存储库模式。但是,我不能在当前项目中使用它,因为由于我不知道它和时间限制,我没有时间重构它。该应用程序的使用量将变得如此之小,以至于数据上下文的低效使用以及您拥有的东西都不会那么重要。一旦它启动并运行,我就可以重构它,但现在我只需要用我当前的结构“推进”。
编辑:我也只是在两者都已经存在时对此进行了测试,并且只将每个对象的 ID 插入到表中,这是可行的。所以我想我可以手动插入任何不存在的对象作为单个插入,然后只将 id 放入链接表中,但我仍然不知道为什么当一个对象存在时,我将其设为空,它确实如此'没用。
【问题讨论】:
标签: .net linq linq-to-sql insert datacontext