2010-11-25 49 views
4

問題摘要: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)!但數據庫中的一切都很好 - 角色AC與用戶有關。

我正在使用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應該能夠發現關係的變化...

+0

注意:在代碼中,我期望給定用戶上的角色列表已經在數據庫中(這就是爲什麼他們只是附加到DataContext )。 – pcoltau 2010-11-25 11:35:40

回答

1

我認爲問題不在Update方法上,但在這裏「DataContext.Users.Where(p => p.ID.equals(user.id) )。FirstOrDefault()「,你正在使用FirstorDefault(),而linq只返回第一條記錄。嘗試刪除FirstOrDefault()並將結果保存在數組上...