c# - LINQ 中的双重过滤

标签 c# sql linq

我需要根据GroupIDs join所有数据,这些GroupIDs归EmpNo所有

public IEnumerable<EmployeeWithEmail> GetAllEmployeesWithEmail(int EmpNo)
{
    using (var context = new SQL_TA_SCOREBOARDEntities1())
    {
        return (from ea in context.View_SystemAdminMembers
                join vh in context.View_HCM on (Int16)ea.EmpNo equals vh.EmpNo
                join rl in context.EmployeeAccessLevels on ea.RoleID equals rl.id into outer_join
                from subjoin in outer_join 

              //need code to join all data according to EmpNo's GroupIDs

                group new
                {
                    ea.EmpNo,
                    subjoin.Role,
                    vh.EmailAddress,
                    vh.LNameByFName,
                    ea.Active

                } by vh.LNameByFName into grp
                let item = grp.FirstOrDefault()
                orderby item.Role ascending
                select new EmployeeWithEmail
                {
                    EmpNum = item.EmpNo ?? 0,
                    Role = item.Role,
                    EmailAddress = item.EmailAddress,
                    LNameByFname = item.LNameByFName,
                    Active2 = item.Active ?? false

                }).ToList();

    }
}

我想我是想过滤两次并加入公共(public)数据,但实际上有两个过滤器,我不知道如何控制。

所以我的输出是这样的:

EmpNo --->  __  01 |  01 |  01 | 01

GroupID --->  __10 |  10 |  20 | 20

Data ---> _________Apple | Apple | Orange | Orange

我可以过滤 EmpNo 01 和 GroupID 10 但如果 EmpNo 属于两个组怎么办? 很抱歉没有找到正确的术语。

提前致谢。

最佳答案

根据您的评论,您尝试生成的 SQL 应该是(我稍微简化了)

SELECT EmployeeAccess.EmpNo, View_SystemAdminMembers.LNameByFName, View_SystemAdminMembers.GroupName,
        View_SystemAdminMembers.Role, View_SystemAdminMembers.Active, View_SystemAdminMembers.EmpNo, 
        View_SystemAdminMembers.RoleID 
FROM EmployeeAccess 
    INNER JOIN View_SystemAdminMembers ON EmployeeAccess.GroupID = View_SystemAdminMembers.GroupID 
WHERE (EmployeeAccess.EmpNo = '01')

这与您在问题中显示的完全不同:

from ea in context.View_SystemAdminMembers
     join vh in context.View_HCM on (Int16)ea.EmpNo equals vh.EmpNo
     join rl in context.EmployeeAccessLevels on ea.RoleID equals rl.id into outer_join
     from subjoin in outer_join

所以我不确定我的回答是否有帮助,但要获得您指定的 SQL,我想您会想要这样做:

var query =
from ea in context.EmployeeAccess
join vsam in context.View_SystemAdminMembers on ea.GroupID equals vsam.GroupID
where ea.EmpNo == "01"
select new
{
    ea.EmpNo, vsam.LNameByFName, vsam.GroupName, vsam.Role, vsam.Active, vsam.EmpNo, vsam.RoleID
};

使用流畅的语法(不是查询语法)看起来有点像:

var query =
    context.EmployeeAccess
    .Join(context.View_SystemAdminMembers, allEA => allEA.GroupID, allVSAM => allVSAM.GroupID, (ea, vsam) => new {ea, vsam})
    .Where(combined => combined.ea.EmpNo == "01")
    .Select(combined => combined.ea.EmpNo, combined.vsam.LNameByFName, combined.vsam.GroupName, combined.vsam.Role, combined.vsam.Active, combined.vsam.EmpNo, combined.vsam.RoleID);

(尽管我承认——我通常会像这样返回整个实体 .Select(combined => combined.ea) 或类似的东西,所以我不能 100% 确定最后一行...)

请注意,在这两种情况下,“var query”都将是一个 IQueryable,这意味着您仍然需要添加一个 ToList 或等效项才能获得您的结果。不过,在执行此操作之前,您需要应用 Tim Burkhart 的答案对其进行任何修改(例如 GroupBy 或其他)。正如他指出的那样,IQueryable 的一个很酷的事情是您不必在一个语句中完成所有操作;你可以像我在上面定义的那样使用query,然后添加类似

的内容
query = query.Where(c => c.LNameByFName.Contains("A"))

或其他。

还有一点要注意——您的返回值完全由 View_SystemAdminMembers 中的项目组成,EmployeeAccess.EmpNo 除外,但由于您正在过滤它,您应该已经知道它是什么。只返回一个 View_SystemAdminMember 对象可能比创建一个新类型更容易。这取决于你。

关于c# - LINQ 中的双重过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22926968/

相关文章:

sql - 根据日期比较多个SQL表数据

c# - 为什么 OfType<> 比 Cast<> 快?

c# - System.BadImageFormatException :Could not load file or assembly … incorrect format when trying to install service with installutil. 可执行文件

c# - SelectNodes 不适用于 stackoverflow 提要

c# - 从 Thread 向 DataGridView 添加行

c# - LINQ to SQL - 如何高效地对多个条件执行 AND 或 OR 搜索

c# - 一对多 LINQ 查询 - 程序集没有 SELECT 的定义

c# - Entity Framework 6 事务回滚

mysql - 使用 SQL 查询将值从一个表插入到另一个表

sql - postgresql 有条件地为每一行生成值