2010-11-25 50 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()并将结果保存在数组上...