Linq To Sql:关系未正确更新

时间:2010-11-25 10:35:41

标签: c# linq linq-to-sql repository-pattern

问题摘要:

使用相同的DataContext来插入和更新与多个角色有关系的User,这些关系在我的LinqToSql类中没有正确更新(但在数据库中很好)。使用一个DataContexts插入和另一个更新工作正常。

详细说明:

我的数据库中有一个User表和一个Role表。为了在它们之间建立多对多的关系,我还有一个UserRoleRelation表(有两个外键给User.ID和Role.ID)。

我有一个测试,其中创建了一个用户,并向该用户添加了两个角色( A B )。然后,我删除角色 A 并添加新角色 C 并更新用户。

但是当我然后选择数据库中的用户时(通过 DataContext.Users.Where(p => p.ID.equals(user.id))。FirstOrDefault())然后用户只有一个UserRoleRelation(角色 A )!但是数据库中的一切都很好 - 角色 A C 都与用户相关。

我正在使用Web服务,因此使用Repository模式 - 为每个服务调用我创建一个新的DataContext - 但是同一个服务可能不止一次地使用相同的Object(例如User,UserRoleRelation或Role),以便它们已经连接到DataContext - 所以当我将对象附加到DataContext时,我捕获潜在的InvalidOperationExceptions(例如,对象已经附加)并忽略它们。

在我的测试中,我使用相同的DataContext来插入和更新用户 - 但是,如果我使用两个不同的DataContexts,那么它工作正常 - 从数据库中正确检索用户!

因此,出于某种原因,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应该能够发现关系的变化......

1 个答案:

答案 0 :(得分:1)

我认为问题不在于Update方法,而在于“DataContext.Users.Where(p =&gt; p.ID.equals(user.id))。FirstOrDefault()”,您正在使用FirstorDefault()和linq只返回第一个记录。尝试删除FirstOrDefault()并将结果保存在数组...