Краткое описание проблемы:
При использовании одного и того же DataContext для вставки и обновления пользователя с отношением к ряду ролей отношения не корректно обновляются в моих классах LinqToSql (ноотлично в базе).Использование одного DataContexts для вставки и другого для обновления работает нормально.
Подробное описание:
У меня есть таблица пользователей и таблица ролей в моей базе данных.Чтобы иметь отношение «многие ко многим», у меня также есть таблица UserRoleRelation (с двумя внешними ключами для User.ID и Role.ID).
У меня есть тест, в котором создается пользователь, и две роли( A и B ) добавлены к этому пользователю.Затем я удаляю роль A , добавляю новую роль C и обновляю пользователя.
Но когда я затем выбираю пользователя в базе данных ( DataContext.Users.Where (p => p.ID.equals (user.id)). FirstOrDefault () ) тогдапользователь имеет только одну UserRoleRelation (на роль A )!Но в базе данных все в порядке - обе роли A и C связаны с пользователем.
Я использую веб-службы и, следовательно, шаблон репозитория - для каждоговызов службы Я создаю новый DataContext - однако одна и та же служба может возиться с одним и тем же объектом (например, 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 должен уметь определять изменения в отношениях ...