У меня есть отношение «многие ко многим» между двумя таблицами, и я хочу получить данные из соединительной таблицы.
Сначала я делюсь источником
Изображение таблиц базы данных:
Изображение объектов модели EF:
Изображение ошибки при отладке:
Я использую следующие правила или стратегии
+Первый подход к базе данных
+диаграмма ЭФ
+Пользовательский поставщик ролей
Проблема в том, что когда я пытаюсь получить данные из соединительной таблицы (user_has_role), я получаю SQL-запрос, а не данные.###
SQL-запрос, который я получаю:
SELECT \r\n [Extent1].[user_id] AS [user_id], \r\n [Extent2].[user_role_name] AS [user_role_name]\r\n FROM [dbo].[user_has_role] AS [Extent1]\r\n INNER JOIN [dbo].[user_role] AS [Extent2] ON [Extent1].[user_role_id] = [Extent2].[user_role_id]
Вот код
Класс поставщика ролей является производным от класса RoleProvider
public class AppRolesProvider : RoleProvider
Все методы переопределены, но работают только с
public override string[] GetRolesForUser(string username)
{
//get all user data from user table for id based on user email
var _user = db.users.Where(u => u.user_email == username).FirstOrDefault();
var _role = (from s in db.users
where (
from c in s.user_role
where s.user_id == _user.user_id
select c
).Any()
select s).ToString();
string[] roleName = { _role };
if (roleName != null)
{
return roleName;
}
else
{
roleName = null;
return roleName;
}
}
Я хочу фактическое имя роли против пользователя (у одного пользователя много ролей или, может быть, одна)
и попытаться получить данные из таблицы соединений, но получить этот запрос
"SELECT \r\n [Extent1].[user_id] AS [user_id], \r\n [Extent2].[user_role_name] AS [user_role_name]\r\n FROM [dbo].[user_has_role] AS [Extent1]\r\n INNER JOIN [dbo].[user_role] AS [Extent2] ON [Extent1].[user_role_id] = [Extent2].[user_role_id]\r\n WHERE [Extent1].[user_id] = @p__linq__0"
не данные
Вот мой метод получить роль в массиве строк
public override string[] GetRolesForUser(string username)
{
//get all user data from user table for id based on user email
int _user_id = Convert.ToInt32(db.users.Where(u => u.user_email == username).Select(i => i.user_id).FirstOrDefault());
// Get role from user_has_role against user id
var _roles = (from _uhr in db.user_has_role
join _r in db.user_role on _uhr.user_role_id equals _r.user_role_id
where _uhr.user_id == _user_id
select new
{
_r.user_role_name
}).ToString();
// store selected
string[] roleName = { _roles };
if (roleName != null)
{
return roleName;
}
else
{
roleName = null;
return roleName;
}
}
вывод изображения в режиме отладки
Таблица соединений не была включена в Entity Framework, так как у нее не было первичного ключа. вы решаете эту проблему, добавляя первичный ключ в соединительную таблицу, а затем обновляя свой файл Edmx.
После обновления модели вы можете получить данные из вашей соединительной таблицы с помощью простого запроса linq.
Разница между двумя случаями:
1) если ваша соединительная таблица не содержит первичного ключа, EF сгенерирует два класса с отношением «многие ко многим»
2) если ваша соединительная таблица содержит первичный ключ, EF сгенерирует 3 класса с: соединительной таблицей в отношении один ко многим с пользователем и один ко многим с user_role
Попробуйте с этим, пожалуйста:
public override string[] GetRolesForUser(string username)
{
//get all user data from user table for id based on user email
int _user_id = Convert.ToInt32(db.users.Where(u => u.user_email == username).Select(i => i.user_id).FirstOrDefault());
// Get role from user_has_role against user id
var _role = db.user_has_role.Where(r => r.user_id == _user_id).Select(r => r.user_role.user_role_name);
// store selected
string[] roleName = _role.ToArray();
if (roleName != null)
{
return roleName;
}
else
{
roleName = null;
return roleName;
}
}
@alaaeddin-hfidhi я пытаюсь сделать так, как вы просили меня добавить первичный ключ в соединительную таблицу, но я не получаю вывод, я обновил свой вопрос, пожалуйста, посмотрите на него и помогите мне
@alaaeddin-hfidhi я хочу, чтобы имя_роли было в массиве строк
Вы можете отправить мне скриншот вашего файла EDMX?
Ты знаешь решение?
это заняло так много времени, я застрял, пожалуйста, помогите мне
Я обновил свой ответ!! если это решение все еще не работает, скажите мне, пожалуйста
большое спасибо за помощь мне. я немного обновил ваше решение и решил мою проблему, спасибо еще раз, братан
Для меня Linq с синтаксисом метода лучше, чем linq с синтаксисом запроса, он делает код более чистым.
да ты прав. еще раз большое спасибо за помощь братан
Я знаю это, но если я не хочу добавлять первичный ключ, что я могу сделать для получения данных?