#orm #entity-framework-4 #mapping #fluent-interface
#orm #entity-framework-4 #сопоставление #fluent-интерфейс
Вопрос:
У меня есть следующее сопоставление для поддержки таблицы «многие ко многим» (User_Role)
modelBuilder.Entity<Role>()
.HasMany<User>(u => u.users)
.WithMany(r => r.roles)
.Map(m =>
m.MapLeftKey("role_id")
m.MapRightKey("user_id")
m.ToTable("User_Role"));
Это отлично работает при сопоставлении многих ролей пользователю и многих пользователей роли. Проблема, с которой я сталкиваюсь, заключается в том, что мне нужно добавить новую строку в таблицу User_Role через объект следующим образом:
public class User_Role
{
[Key Column(Order=1)]
public int role_id {get;set;)
[Key Column(Order=1)]
public int user_id {get;set;)
}
Всякий раз, когда я пытаюсь получить доступ к этому объекту следующим образом:
dbContext.User_Role.Add(new User_Role {user_id ....
EF ищет несуществующую таблицу с именем User_Role1 … это добавление ‘1’ к имени таблицы.
Затем я попытался добавить:
[Table("User_Role")]
Это позаботится о добавлении «1», но теперь я получаю эту ошибку:
«Набор объектов ‘RoleUser’ со схемой ‘dbo’ и таблицей ‘User_Role’ уже определен. Каждый набор объектов должен ссылаться на уникальную схему и таблицу «
Я смог подтвердить, что следующие строки вместе вызывают проблему, но мне нужны они оба
m.ToTable("User_Role") and public class User_Role..
Любые предложения были бы замечательными…Я в тупике.
Ответ №1:
Вы не можете представить таблицу соединений в отношениях «многие ко многим» классом сущности в вашей модели. Эта таблица соединений управляется EF, и вы не можете получить прямой доступ к этой таблице. Если вы хотите создать связь между существующим пользователем и существующей ролью, вы должны сделать это, используя эти две сущности:
var user = dbContext.Users.Single(u => u.id == user_id);
var role = dbContext.Roles.Single(r => r.id == role_id);
// if you don't have lazy loading and don't instantiate the collection
// in the constructor, add this: user.roles = new List<Role>();
user.roles.Add(role);
dbContext.SaveChanges();
Это приведет к записи записи для новой связи (пары (user_id,role_id)) в таблицу соединений.
Редактировать
Если у вас есть только два ключевых свойства и вы не хотите загружать пользователя и роль из базы данных, вы можете работать с прикрепленными «заглушками»:
var user = new User { id = user_id, roles = new List<Role>() };
var role = new Role { id = role_id };
dbContext.Users.Attach(user);
dbContext.Roles.Attach(role);
user.roles.Add(role);
dbContext.SaveChanges();