C#CodeSmith LINQ to SQL问题DELETE操作

时间:2010-07-15 17:35:08

标签: c# asp.net linq linq-to-sql codesmith

在我正在处理的项目中,我需要从数据库中删除“用户”。这个“用户”有两个引用它的外键的表。当硬删除时,我试图删除表A和表B中具有“用户”外键然后删除该“用户”记录的所有记录。这都是在存储库中使用对象工厂完成的。

代码如下:

public void RemoveUserByUserId(int userId)
{
var user = m_context.User.GetByKey(userId);

ObjectFactory.Inject(m_context);

UserTokenRepository.RemoveUserTokensByUserId(userId);
UserMappingRepository.RemoveUserMappingsByUserId(userId);

m_context.User.DeleteOnSubmit(user);

m_context.SubmitChanges();

ObjectFactory.ResetDefaults();
}

public static void RemoveUserTokensByUserId(int userId)
{
var dataContext = ObjectFactory.GetInstance<DataContext>();
var userTokens = dataContext.UserToken.ByUserId(userId);
dataContext.UserToken.DeleteAllOnSubmit(userTokens.AsEnumerable());
}

public static void RemoveUserMappingsByUserId(int userId)
{
var dataContext = ObjectFactory.GetInstance<DataContext>();
var userMappings= dataContext.UserMapping.ByUserId(userId);
dataContext.UserMapping.DeleteAllOnSubmit(userMappings.AsEnumerable());
}

如果每个表都有一条记录,那么它可以正常工作。如果一个表有多个,只能在UserToken和UserMappings上发生,我会收到以下错误。

System.ArgumentException was unhandled by user code
Message=An item with the same key has already been added.
  Source=mscorlib
  StackTrace:
       at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
       at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
       at System.Data.Linq.ChangeProcessor.EdgeMap.Add(MetaAssociation assoc, TrackedObject from, TrackedObject to)
       at System.Data.Linq.ChangeProcessor.BuildEdgeMaps()
       at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
       at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
       at XXXX.XXXX.XXXX.XXXXDataContext.SubmitChanges(ConflictMode failureMode) in XXXX:line 519
       at System.Data.Linq.DataContext.SubmitChanges()
       at XXXX.UserRepository.RemoveUserByUserId(Int32 userId) in XXXX:line 146
       at XXXX(Int32 profileUserId) in XXXX:line 948
       at XXXX(Int32 profileUserId) in XXXX:line 165
       at SyncInvokeUnregisterUserForActivationFailed(Object , Object[] , Object[] )
       at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
       at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)

出于隐私原因,我不得不放入XXXX。我读到的是,然而LINQ正在预存SQL的更改,它将它放入一个字典中,并且不知何故,两件事的关键是相同的,并且在更改发生之前它是错误的。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

我有点在黑暗中拍摄,并假设你如何阅读它是正确的,伴随着我一路上的一点点痛苦。

要删除的表是否有自己的主键,或者您使用外键作为pk? (嗯,你知道我的意思......听起来他们没有自己独立的主键,linq知道)'

linq使用GetHash方法从主键字段构造一个唯一的id。我猜这些字段是复制的,因此字典问题......问题不是由具有相同键ID的2个不同表引起的。

我猜这些包含多个项目的表格是一种在多对多连接中间的表格。一个快速而又脏的修复方法是向它们添加一个自动增量列并将其分配给主键(否则尝试使用多字段pk - 我没有尝试过使用linq deliberatley)。

我希望这能为您提供一些想法...您可以在部分类中覆盖GetHashCode,以另一种方式修复您的问题...但是您应该只包含数据中不变的单个项目的部分)

答案 1 :(得分:0)

这是一个老问题但是我们从来没有能够同时删除这两个表。我们的解决方案是从一个中删除另一个,并在两者之间提交更改。