#entity-framework #ef-code-first
#entity-framework #ef-code-first
Вопрос:
Я пытаюсь сначала добавить новую запись в таблицу ссылок, используя код entityframework. То, что у меня есть, — это многие ко многим на User
и Role
. Мой сценарий заключается в том, что когда я меняю роль для пользователя, я удаляю все их предыдущие роли и добавляю новые роли следующим образом:
//Delete all associated roles for user
var roleUser = db.Users.Include(r => r.Roles).FirstOrDefault(u => u.UserId == user.UserId);
var usersRoles = roleUser.Roles;
usersRoles.ForEach(role => roleUser.Roles.Remove(role));
//add the new roles
roleUser.Roles.AddRange(detachedUser.Roles);
db.SaveChanges();
Таким образом, он отлично удаляет их. Но при добавлении новых ролей это добавляет их не только в таблицу ссылок, но и в Role
таблицу. Добавляется совершенно новая роль без RoleName
. user.Roles
будет содержать элемент со следующими данными:
RoleId;//1 <-- this Id exists in the database already but yet still it creates one instead of a linktable record.
RoleName;//null
Как мне запретить EF добавлять совершенно новую запись и просто добавить запись в таблицу ссылок?
Обновление: в итоге я сделал это:
var roleUser = db.Users.Include(r => r.Roles).FirstOrDefault(u => u.UserId == user.UserId);
var roles = db.Roles;
foreach (var role in roles)
{
if (user.Roles.Any(r => r.RoleId == role.RoleId))
{
roleUser.Roles.Add(role);
}
else
{
roleUser.Roles.Remove(role);
}
}
db.SaveChanges();
Комментарии:
1. По-видимому, это решено, но не могу понять, что ее решило. Не могли бы вы, пожалуйста, опубликовать еще раз ту часть ответа, которая предотвращает создание новой роли.
Ответ №1:
попробуйте сохранить перед добавлением новых ролей пользователю
//Delete all associated roles for user
var roleUser = db.Users.Include(r => r.Roles).FirstOrDefault(u => u.UserId == user.UserId);
var usersRoles = roleUser.Roles;
usersRoles.ForEach(role => roleUser.Roles.Remove(role));
db.SaveChanges();
roleUser.Roles.AddRange(user.Roles); //add the new roles
db.SaveChanges();
Редактировать:
Взгляните на это :
roleUser.Roles.AddRange(user.Roles); //add the new roles
откуда user.Roles
берутся?
Комментарии:
1. Я все еще сталкиваюсь с той же проблемой после добавления вторых сохранений.
2. Я думаю, что это способ, которым я добавляю новые роли. Вероятно, мне придется получить их все из базы данных и добавить их
3. когда у вас возникают подобные проблемы, вы также можете захотеть взглянуть на свою конфигурацию привязки. У меня были подобные проблемы в прошлом.
4. изменило ли что-нибудь их возвращение из базы данных?
5. @lol coder, вы нашли причину создания ролей. объекты были замечены как новые. рад видеть, что вы решили эту проблему 🙂
Ответ №2:
Я думаю, проблема в том, что вам нужно прикрепить свои роли, прежде чем добавлять их пользователю.
вам также не нужно удалять их все, просто удалите удаленные, а затем только добавьте новые.
Комментарии:
1. Я согласен с @moi_meme в той части, где вам нужно удалить только те, которые необходимо удалить. С другой стороны, я не думаю, что это проблема, которая коснулась подключенных / отсоединенных состояний. поскольку объекты никогда не отсоединяются.
2. @Alexandre Brisebois — Я написал, что из-за его переменной называется DetachedUser
3. мой плохой, я не заметил эту часть
Ответ №3:
Для каждого добавляемого вами рулона вы могли бы попробовать проверить или установить состояние объекта. Например, здесь я установил для set значение unchaged. Таким образом, он не будет пытаться вставить или обновить его.
myContext.Entry(roll).State = EntityState.Unchanged
Больше информации здесь:
http://blogs.msdn.com/b/adonet/archive/2011/01/29/using-dbcontext-in-ef-feature-ctp5-part-4-add-attach-and-entity-states.aspx
Комментарии:
1. верно, но если бы он сохранил перед попыткой добавления новых ролей, разве состояние объектов не осталось бы неизменным (после сохранения)