如何使用Linq c#实现自联接以获得完整的结果?

时间:2014-07-10 09:10:59

标签: c# sql linq entity-framework self-join

在我的场景中,我需要显示其经理ID为@Id的所有员工。

层次结构就像

Manager --- Employee
john --- smith
john --- sam
sam --- peru
sam --- karim

我首先使用linq和Entity Framework DB。

我需要向特定经理展示所有员工,让我们与id = 2

取得联系

我应用了2个不同的查询,但结果是相同的,即它只显示第一层次约翰只有2名员工史密斯和山姆但是山姆里面的员工也必须显示不检索..

这是我的代码:

var lstAllUser = (List<Entities.User>)Session["AllUsers"];

int pID = Convert.ToInt32(ddlSelectedValue);

 //query 1 which i try first        
var lstSelectedEmployees1 = lstAllUser.Where(emp => emp.ManagerId == pID)
                                      .Select(emp => new { 
                                          EmployeeName = emp.UserDetail.Name, 
                                          ManagerName = emp.Manager.UserDetail.Name 
                                    }).ToList();

//query 2 
var lstSelectedEmployees = (from employee in lstAllUser
                            where employee.ManagerId == pID
                            join e1 in lstAllUser 
                            on employee.ManagerId equals e1.UserID
                            select new
                            {
                                ManagerName = e1.UserDetail.Name,
                                EmployeeName = employee.UserDetail.Name
                            }).ToList();


gvEmployeeManager.DataSource = lstSelectedEmployees;
gvEmployeeManager.DataBind();

Aspx就像;

<asp:GridView ID="gvEmployeeManager" runat="server" AutoGenerateColumns="False" GridLines="Vertical" CssClass="table table-striped">
<Columns>
    <asp:BoundField DataField="EmployeeName" HeaderText="Employee" />
    <asp:BoundField DataField="ManagerName" HeaderText="Manager" />
</Columns>
</asp:GridView>

需要帮助!!

1 个答案:

答案 0 :(得分:1)

假设您想要回复向经理报告的所有员工,而不仅仅是直接向他们报告的员工......

我不认为可以在LINQ中的单个查询中执行此操作。如果您使用的是SQL Server(2005+),那么您可以执行一个具有递归公用表表达式的存储过程来执行此操作(此处的示例:http://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx

在C#/ LINQ中,您将被简化为在递归代码循环中进行多次查询。 下面是一个例子

public Dictionary<string, string> GetEmployeesAllLevels(int managerId)
{
  return GetEmployeesAllLevels(managerId, null);
}

private Dictionary<string, string> GetEmployeesAllLevels(int managerId, Dictionary<string, string> existingList)
{
  if (existingList == null) existingList = new Dictionary<string, string>();
  var lstSelectedEmployees1 = lstAllUser.Where(emp => emp.ManagerId == managerId)
                                      .Select(emp => new { 
                                          EmployeeName = emp.UserDetail.Name, 
                                          ManagerName = emp.Manager.UserDetail.Name,
                                          UserId = emp.UserId 
                                    }).ToList();
  foreach(var emp in lstSelectedEmployees1)
  {
    existingList.Add(emp.EmployeeName, emp.ManagerName);
    existingList = GetEmployeesAllLevels(emp.UserId, existingList);
  }
  return existingList;
}