2010-07-15 44 views
1

在我正在處理的項目中,我需要從數據庫中刪除「用戶」。這個「用戶」有兩個引用它的外鍵的表。當硬刪除時,我試圖從表A和表B中刪除所有具有「用戶」外鍵的記錄,然後刪除該「用戶」記錄。這全部在存儲庫內完成並使用對象工廠完成。C#CodeSmith LINQ to SQL問題DELETE操作

的代碼如下:

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存儲preping SQL的變化它把它放入一個字典,不知怎的,兩個事情的關鍵是相同的,它發生變化之前的錯誤。

任何幫助將非常感激。

回答

0

這是一個老問題,但我們無法同時對兩個表進行刪除。我們的解決方案是從另一個刪除另一個,並在兩者之間進行更改。

0

我有點在這裏黑暗中拍攝,並假設你閱讀它的方式是正確的,伴隨着我一路上的一點痛苦。

做你正在刪除的表有自己的主鍵還是你使用外鍵作爲PK? (以及你知道我的意思......它聽起來不像他們有自己獨立的主鍵,linq知道)'

linq使用GetHash方法從主鍵字段構造一個唯一的ID ..我猜測,這些字段重複,因此字典問題......問題不是由具有相同的密鑰ID的2個不同的表引起的。

我猜測這些表中有多個項目是一種在多對多連接的中間。一個快速和骯髒的修復將是添加一個自動增量列給他們nd分配這個主鍵(否則嘗試使用多字段pk - 我沒有;真的試過linq意見)。

我希望這給你一些想法...你可以重寫GetHashCode在一個部分類來解決你的問題的另一種方式...但是你應該只包括你的數據的部分是不變的跨單個項目)

+0

實際上每個表都有一個主鍵。結構如下。用戶表[pk:user_id] UserToken表 - [pk:token_id(guid)] [fk:user_mapping_id] [fk:user_id] UserMapping表 - [pk:user_mapping_id] [fk:user_id] – 2010-07-15 18:54:25