問題摘要:LINQ to SQL的:關係不正確更新
使用相同的DataContext既INSERT和UPDATE有關係的一些角色的用戶,關係不正確在我的LinqToSql類更新(但在數據庫中罰款)。使用一個DataContexts插入和另一個更新工作正常。
詳細描述:
我有一個用戶表,並在我的數據庫角色表。要在它們之間建立多對多關係,我還有一個UserRoleRelation表(帶有兩個User.ID和Role.ID的外鍵)。
我有在其中創建一個用戶測試和兩個角色(甲和乙)加入到該用戶。然後刪除角色A並添加新角色C並更新用戶。
但是,當我然後在數據庫中選擇用戶(由DataContext.Users.Where(p值=> p.ID.equals(user.id))。FirstOrDefault()),則用戶僅具有一個UserRoleRelation (作用A)!但數據庫中的一切都很好 - 角色A和C與用戶有關。
我正在使用Web服務,因此存儲庫模式 - 爲每個服務調用我創建一個新的DataContext - 但同一個服務可能不止一次地擺弄同一對象(例如用戶,UserRoleRelation或角色),以便它們已經附加到DataContext - 所以當我將對象附加到DataContext時,我正在捕獲潛在的InvalidOperationExceptions(例如,對象已連接)並忽略它們。
在我的測試中,我使用相同的DataContext插入和更新用戶 - 但是,如果我使用兩個不同的DataContext,那麼它工作正常 - 用戶從數據庫中正確檢索!
因此,出於某種原因,DataContext內部的緩存被搞亂了。
這裏是我的UpdateUser兩個方法:
private User UpdateUser(User user)
{
foreach (UserRoleRelation relation in user.UserRoleRelations)
{
if (relation.Role != null)
{
TryAttach(DataContext.Roles, relation.Role); // same as DataContext.Roles.Attach(relation.Role)
}
}
// attach the new user as modified
TryAttach(DataContext.Users, user, true); // same as DataContext.Users.Attach(user, true), but is that the correct way to do it?
// update the relations (figure out which are removed, added and unchanged)
IEnumerable<UserRoleRelation> oldRelations = DataContext.UserRoleRelations.Where(p => p.UserID.Equals(user.ID)).ToList();
// mark for deletion (those elements that are in the old list, but not in the new)
IEnumerable<UserRoleRelation> deletionList = oldRelations.Except(user.UserRoleRelations, userRoleRelationComparer).ToList();
DataContext.UserRoleRelations.DeleteAllOnSubmit(deletionList);
// mark for insert (those that are in the new list, but not in the old)
IEnumerable<UserRoleRelation> insertionList = user.UserRoleRelations.Except(oldRelations, userRoleRelationComparer).ToList();
DataContext.UserRoleRelations.InsertAllOnSubmit(insertionList);
// attach the rest as unmodified (those that are in both lists)
IEnumerable<UserRoleRelation> unmodifiedList = oldRelations.Intersect(user.UserRoleRelations, userRoleRelationComparer).ToList();
TryAttachAll(DataContext.UserRoleRelations, unmodifiedList);
DataContext.SubmitChanges();
// return the updated user (in order to be sure that all relations are update, we fetch the user from the DB)
User updatedUser = GetUser(user.Email); // same as DataContext.Users.Where(p => p.Email.Equals(user.Email)).FirstOrDefault();
return updatedUser;
}
我在做什麼錯? - 我敢肯定,當我在測試中使用相同的DataContext時,「將用戶附加到DataContext」會引發異常(它已被附加),這可能是我沒有得到正確關係的原因 - 但LinqToSql應該能夠發現關係的變化...
注意:在代碼中,我期望給定用戶上的角色列表已經在數據庫中(這就是爲什麼他們只是附加到DataContext )。 – pcoltau 2010-11-25 11:35:40