与其他问题类似的错误,但不完全相同,我不想附加任何内容。
我要做的是在链接表中插入一个新行,特别是UserAccomplishment。关系在LINQ to User和Accomplishment Tables中设置。
我有一个通用插入函数:
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提供两个适当的对象,如果用户或成就已经存在,这将自然地废弃。它仅在用户和成就不存在时才有效。我期待这种行为。什么工作只是给userAccomplishment对象一个user.id和achievement.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
好的,在这里我基本上检查所提供的用户和成就是否已经存在于db中,如果是这样,则调用一个适当的构造函数,该构造函数将保留已存在的任何内容为空,但提供其余信息以便插入可以成功。 / p>
然而,在尝试插入时:
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)先发制人'使用存储库模式答案' - 我知道这种方式很糟糕,我应该使用存储库模式。但是,我不能在当前项目中使用它,因为我没有时间重构,因为我不知道它和时间限制。应用程序的使用量非常小,以至于使用datacontext的效率低下,以及您将无关紧要的内容。我可以在它启动并运行后重构它,但是现在我只需要用现有的结构“推进”它。
编辑:我刚刚测试了这两个已经存在,并且只将每个对象的ID插入到表中,这是有效的。所以我想我可以手动插入不存在的任何对象作为单个插入,然后将id只放入链接表中,但我仍然不知道为什么当一个对象存在时,我把它变为空,它会'工作。
答案 0 :(得分:2)
首先,我认为你工作太辛苦了,但这是可以理解的。
让我看看你是否理解你要做的事情:你想要更新一个跟踪用户和成就的关联表。无论事先存在什么,当您完成时,您需要一个有效的UserAccomplishment记录,完成有效和有效的关系。让我们从:
开始public void AddUserAccomplishment(user User, accomplishment Accomplishment)
{
using (LCFDataContext dc = new LCFDataContext())
{
// Substitute <UserName> for any other unique field in the record.
var tempUser = dc.Users
.Where(a => a.UserName.ToLower() == user.UserName.ToLower())
.SingleOrDefault();
// Using SingleOrDefault() creates an empty User entity object if
// a matching record can't be found, which means the Id field will
// be equal to zero.
if (tempUser.Id == 0)
{
// Populate the empty tempUser entity object
tempUser.UserName = user.UserName;
.
.
.
dc.Users.InsertOnSubmit(tempUser);
}
// Do the same thing for the Accomplishment.
var tempAccomplishment = dc.Accomplishments
.Where(a => a.Title.ToLower() == accomplishment.Title.ToLower())
.SingleOrDefault();
if (tempAccomplishment.Id == 0)
{
// Populate the empty tempAccomplishment entity object
tempAccomplishment.Title = accomplishment.Title;
.
.
.
dc.Accomplishments.InsertOnSubmit(tempAccomplishment);
}
// Now, you need to make sure that the UserAccomplishment entity object
// doesn't already exist.
if (dc.UserAccomplishments
.Where(a => a.User.Id == tempUser.Id
&& a.Accomplishment.Id == tempAccomplishment.Id)
.Count == 0)
{
UserAccomplishment userAccomplishment = new UserAccomplishment();
userAccomplishment.User = tempUser;
userAccomplishment.Accomplishment = tempAccomplishment;
dc.UserAccomplishments.InsertOnSubmit(userAccomplishment);
}
else
{
// The UserAccomplishment record already exists, so throw an
// exception or display an error message.
}
dc.SubmitChanges();
}
}
如果这有帮助,请告诉我......