LINQ中的双重过滤

  • 本文关键字:过滤 LINQ c# sql linq
  • 更新时间 :
  • 英文 :


我需要根据GroupID加入所有数据,这些GroupID归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();
    }
}

我想我试图过滤两次并连接公共数据,但实际上有两个过滤器,我不知道如何控制。

所以我的输出应该是:

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对象可能比创建一个新类型更容易。这取决于你。

我并没有真正按照你的要求行事。也许它可以被改写,或者被赋予更多的上下文,或者格式不同?

但我想我会提出一些建议,可能会帮助你达到你想要去的地方。

1-函数名称意味着该人员将提供一封电子邮件,并通过该电子邮件接收多个Employee对象。但它似乎接受了员工id并返回了EmployeeWithEmail列表。考虑重命名函数以匹配它正在执行的操作。还应考虑返回IEnumerable<Employee>IEnumerable<IEmployeeEmailView>

2-这个功能做了很多工作。(弄清楚它在做什么需要几秒钟以上的时间)。在这种情况下,我会从简单开始。不要进行分组或排序或其他任何操作。有一些函数返回这个结果:

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 

以类似IEnumerable<Employee> 的形式

public class Employee {
     public int Id { get; set; }
     public string Role { get; set; }
     public string EmailAddress { get; set; }
     public string Name { get; set; }
     public bool IsActive { get; set; }
}

从那以后,事情就更容易处理了。您不必使用LINQ to SQL。你可以做…

IEnumerable<Employee> employees = <your renamed function>();
var employeesGroupedByName = employees.GroupBy(e => e.Name);

希望这能让你更轻松。它不能解决你的问题,但我认为它可能会让事情变得不那么复杂/更容易处理。

写得很完整,可能是这样的:

public class EmployeeRepository {
    public IEnumerable<Employee> GetAll() {
        // This function won't compile. I don't know the syntax for this type of LINQ
        using (var context = new SQL_TA_SCOREBOARDEntities1()) {
            return (from ea in context.View_SystemAdminMembers
            join vh in context.View_HCM on (Int16)ea.EmpNo
            join rl in context.EmployeeAccessLevels on ea.RoleID equals rl.id into outer_join
        }
    }
    public IEnumerable<Employee> GetAllEmployeesWithEmployeeId(int employeeId) {
        return GetAll().Where(e => e.Id == employeeId).ToList();
    }
    public IEnumerable<Employee> SomeOtherFunctionThatDoesWhatYouWantToDoFromThisPost() {
        // You could also create a class that extends IEnumerable<Employee> to
        // encapsulate the logic so that the repository doesn't have a million functions
    }
}

这就是我给你的全部。如果问题能解释得更好一点,我可以给出一个更完整的答案,但希望这能让你走上正轨。

相关内容

  • 没有找到相关文章

最新更新