Как получить данные из Junction Table, используя DB First Approach в MVC - PullRequest
0 голосов
/ 10 апреля 2019

У меня есть связь «многие ко многим» между двумя таблицами, и я хочу получить данные из соединительной таблицы.

Сначала я делюсь некоторыми источниками

Изображение таблиц базы данных:

https://imgur.com/BDvPiQa

Изображение сущностей модели EF:

https://imgur.com/mFHPjfN

Изображение ошибки при отладке:

https://imgur.com/lL7DE72

Я использую следующие правила или стратегии

+ Первый подход к базе данных

+ Диаграмма EF

+ Поставщик пользовательских ролей

Проблема заключается в том, что в то время как япытаюсь получить данные из Junction Table (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]

Вот некоторый код

Role Provider Class isПолучено из RoleProvider Class

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;
            }
        }

Я хочу фактическое 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;
        }
    }

выходное изображение в режиме отладки

Обновлено

EDMX Image

1 Ответ

0 голосов
/ 10 апреля 2019

Соединительная таблица не была включена 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;
        }
    }
...