SQL 使用 JOIN to LINQ 查询

SQL query with JOIN to LINQ

我在将以下查询转换为 Linq 时遇到问题:

SELECT u.UserId, 
       u.UserName, 
       r.RoleName 
FROM   aspnet_users u 
       INNER JOIN aspnet_UsersInRoles ur ON u.UserId = ur.UserId 
       INNER JOIN aspnet_Roles r ON r.RoleId = ur.RoleId AND 
                                    r.RoleName IN ('SuperAdmin', 'AdminExtended', 'ExpertExtended') 
ORDER  BY u.UserName 

我尝试了几个 Linq 查询,但我不确定如何构建角色 <-> 用户关系,以便我可以从每个用户那里获取角色,EF 使用 [=22 在它们之间创建映射=] table

这是我尝试过的方法:

var query = from u in context.aspnet_Users
            from r in u.aspnet_Roles
            where r.RoleName == "SuperAdmin" || r.RoleName == "AdminExtended" || r.RoleName == "ExpertExtended"
            select u;

var query = from u in context.aspnet_Users
            where u.aspnet_Roles.Any(r => r.RoleName == "SuperAdmin" || r.RoleName == "AdminExtended" || r.RoleName == "ExpertExtended")
            select u;

尝试如下:

var roleNames = new List<string>(){"SuperAdmin","AdminExtended","ExpertExtended"};
from u in context.aspnet_Users
join uir in context.aspnet_UsersInRoles on u.UserId = uir.UserId
join r in context.aspnet_Roles on r.RoleId = uir.RoleId
where (roleNames.Contains(r.RoleName))
select new {UserId = u.UserId, UserName = u.UserName , RoleName = r.RoleName}

您可以在 msdn 文档中查看有关 linq 连接查询 here 的更多详细信息。

与 Jenish 相同,但如果角色是用户的导航 属性,则可以避免加入

from u in context.aspnet_Users
join r in context.aspnet_UsersInRoles  on u.UserId equals r.UserId
select new {u.UserName, r.aspnet_Role.RoleName}

Nav 属性 aspnet_Role 可能有不同的名称 IDK

你在第一次尝试中接近:

from u in context.aspnet_Users
from r in context.aspnet_UsersInRoles
where u.UserId == r.UserId
select new {u.UserName, r.aspnet_Role.RoleName}

基于 EF 生成连接 table aspnet_UsersInRoles 和您在所需、生成的 SQL 查询中提到的一些字段名称,我假设 POCO 类似于以下内容(此答案的其余部分取决于这些假设):

public class User
{
    public int UserId { get; set; } // just assuming int key ID
    public string UserName { get; set; }
    public virtual ICollection<Role> Roles { get; set; }
}

public class Role
{
    public int RoleId { get; set; }
    public string RoleName { get; set; }
    public virtual ICollection<User> Users { get; set; }
}

使用此设置,您应该能够通过以下方式获得您正在寻找的 SQL 输出:

from r in context.Roles
where r.RoleName == "SuperAdmin" || r.RoleName == "AdminExtended" || r.RoleName == "ExpertExtended"
from u in r.Users
orderby u.UserName
select new {u.UserId, u.UserName, r.RoleName};

注意 EF 和 L2E 为您做了所有的魔法:它甚至从关系名称推断出两个 POCO 之间的关系。

仅使用上面的代码,我将其放入我的编译器中,将 var q 设置为显示的查询,然后将 q.ToString() 转储出来 - 这就是我得到的:

SELECT
    [Extent1].[RoleId] AS [RoleId],
    [Join1].[UserId] AS [UserId],
    [Join1].[UserName] AS [UserName],
    [Extent1].[RoleName] AS [RoleName]
    FROM  [dbo].[Roles] AS [Extent1]
    INNER JOIN  (SELECT [Extent2].[Role_RoleId] AS [Role_RoleId], [Extent3].[UserId] AS [UserId], [Extent3].[UserName] AS [UserName]
        FROM  [dbo].[UserRoles] AS [Extent2]
        INNER JOIN [dbo].[Users] AS [Extent3] ON [Extent3].[UserId] = [Extent2].[User_UserId] ) AS [Join1] ON [Extent1].[RoleId] = [Join1].Role_RoleId]
    WHERE [Extent1].[RoleName] IN (N'SuperAdmin',N'AdminExtended',N'ExpertExtended')
    ORDER BY [Join1].[UserName] ASC

我认为这几乎抓住了它。