Запрос Entity Framework «многие ко многим»: свойство навигации не сгенерировано

#entity-framework-4

#entity-framework-4

Вопрос:

У меня есть две таблицы, User и UserRole к которым они подключены с помощью таблицы ссылок UserInRole

Когда я генерирую модель сущности, по какой-то причине сущность UserInRole не генерируется. И, как вы можете видеть из рисунка, Entity Framework поняла, что существует взаимосвязь «многие ко многим» между User и UserRole :

введите описание изображения здесь

Мне нужно реализовать запрос следующим образом

 select ur.Name from [User] as u
inner join UserInRole uir on uir.UserId = u.Id
inner join UserRole ur on ur.Id = uir.UserRoleId
where u.Username = 'magename'
  

Я использую универсальный репозиторий, если бы свойство навигации существовало, запрос выглядел бы следующим образом:

 from u in repository.AsQueryable<User>()
join uir in repository.AsQueryable<UserInRole>() on u.Id equals uir.UserId
join ur in repository.AsQueryable<UserRole>() on uir.UserId equals ur.Id
where u.Username == userName
select ur.Name
  

Но Entity Framework не генерирует UserInRoles свойство навигации и связанную с ним UserInRole сущность, поэтому возникает вопрос, что мне делать в этой ситуации? Должен ли я удалить ссылку между UserInRole и UserRole , чтобы получить объект UserInRole , сгенерированный в модели, или есть какой-либо способ получить запрос, который я описал выше, без каких-либо изменений в базе данных?

ОБНОВЛЕНО

похоже, мне нужно сделать что-то подобное

 stirng[] roles = (from u in repository.AsQueryable<User>()
         where u.Username == userName
         select ur.UserRoles.Select(x => x.Name)).ToArray<string>();
  

получение ошибки Cannot implicitly convert type 'System.Collections.Generic.List<System.Collections.Generic.IEnumerable<string>>' to 'string[]' есть идеи?

Комментарии:

1. Ваша проблема в том, что при первом выборе в вашем ОБНОВЛЕННОМ разделе будет выбран список пользователей — неважно, содержит ли он одного или нескольких пользователей, но это список пользователей — и из них вы выбираете имена их пользовательских ролей — так что у вас есть список массивов, в основном — это то, о чем сообщает вам ошибка.

Ответ №1:

Вам не нужна эта таблица ссылок в вашей модели EF! В этом прелесть EF!!

Проверьте свою сущность User — у нее есть UserRoles свойство навигации — это набор всех ролей, в которых находится этот пользователь.

Проверьте entity UserRole : у него есть свойство навигации Users , в котором указаны все пользователи, выполняющие эту роль.

С помощью этих двух многозначных свойств навигации вы можете выражать любые запросы, которые вам могут понадобиться:

  • найдите всех пользователей для заданной роли (найдите UserRole сущность и перечислите ее .Users свойство)
  • найдите все роли для данного пользователя (найдите User и перечислите его .UserRoles )

EF и EDM как бы «скрывают» от вас эту таблицу ссылок — на самом деле вам это не нужно, когда вы выражаете свое намерение в концептуальной модели; эти таблицы ссылок являются просто «необходимым злом» в реляционных базах данных, поскольку эти базы данных не могут моделировать отношения m: n каким-либо другим способом.

Обновление: итак, вы, похоже, хотите найти список всех пользовательских ролей (их имен), в которых участвует конкретный пользователь — вы можете выразить это примерно так:

 // find the user in your "dbContext" (or via your repository)
var user = _dbContext.Users.FirstOrDefault(u => u.Name == "magename");

// from the list of UserRoles on that user, select the names only
var userRolesNames = user.UserRoles.Select(ur => ur.Name).ToList();
  

Комментарии:

1. Да, я видел эти свойства, и я подумал, что это какая-то волшебная вещь EF… Пытаюсь разобраться в запросе после этой неожиданной путаницы.