如何在 MVC 中使用 DB First Approach 从连接表中获取数据

Posted

技术标签:

【中文标题】如何在 MVC 中使用 DB First Approach 从连接表中获取数据【英文标题】:How to get data from Junction Table using DB First Approach in MVC 【发布时间】:2019-08-31 06:37:45 【问题描述】:

我有 2 个表之间的多对多关系,我想从联结表中检索数据。

我先分享一些资源

数据库表图片:

https://imgur.com/BDvPiQa

EF 模型实体图片:

https://imgur.com/mFHPjfN

调试时的错误图片:

https://imgur.com/lL7DE72

我正在使用以下规则或策略

+数据库优先方法

+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]

这是一些代码

Role Provider 类派生自 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;
            
        

我想要针对用户的实际角色名称(一个用户有多个角色或者可能一个)

更新

Updated db image

并尝试从联结表中检索数据但获取此查询

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

output image in debug mode

更新

EDMX Image

【问题讨论】:

【参考方案1】:

实体框架未包含联结表,因为它没有主键。您可以通过向联结表添加主键然后更新您的 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 文件的截图发给我吗? 我卡住了这么长时间,请帮帮我

以上是关于如何在 MVC 中使用 DB First Approach 从连接表中获取数据的主要内容,如果未能解决你的问题,请参考以下文章

为 EF-db- first 设置 mvc-mini-profiler

使用命令行如何在 ASP.NET 中首先从 DB 搭建脚手架 - 而不是 ASP.NET Core MVC?

如何在MVC 5的类库项目中使用Entity Framework 6 Code First

我应该如何在 MVC3 中使用 Code First Entity Framework (4.1) 声明外键关系?

使用 Entity Framework 6.1 和 MVC 5 从数据库中使用 Code First 后如何同步模型?

如何在 .net 核心上使用 ef 核心在 postgresql(db first)中映射枚举