我坚持在LINQ中进行分层查询 - 我正在进行我的第一个ASP.NET项目,因此缺乏知识和经验。我基本上在EF6,C#和MVC 5上做项目。 所以,我无法弄清楚如何获得以下分层数据。
我有一个员工表,一个employeeMap表和一个目标表。 EmployeeMap将目标映射到员工。目标是分层的,所以目标在一元关系中有一个父目标,这里我的目标类有点简化:
public class Goal
{
public int ID { get; set; }
public string Name { get; set; }
public int? ParentID { get; set; }
public virtual Goal Parent { get; set; }
}
我需要一个映射到员工的目标列表,以及其所有父目标。我可以将映射到员工的目标及其父目标,但不能将父级父级等等提升到顶层,其中parentID将为null。这是我的目标和直接父母的查询。
viewModel.EmpGoals = (
from g in db.Goals
join m in db.EmployeeMaps on g.ID equals m.GoalID
join e in db.Employees on m.EmployeeID equals e.ID
where m.EmployeeID == id.Value
select new EmployeeGoal
{
EmployeeID = e.ID,
LastName = e.LastName,
FirstName = e.FirstName,
GoalID = g.ID,
Name = g.Name,
ParentID = g.ParentID,
Parent = g.Parent,
WeightPct = m.WeightPct,
Locked = m.State.Equals(1),
Activities = g.Activities
}).ToList();
}
所以我想我需要一个分层查询,递归地运行所有父节点并返回每个父节点(或者至少只是父树的顶部,或者可能是root),但是如何使用LINQ来做到这一点,或者我应该考虑一些原始SQL给我这个回来?
谢谢:)
答案 0 :(得分:0)
是否必须是单个查询?从数据层服务调用方法后,可能会返回列表:
ExampleDataLayerService dlSvc = new ExampleDataLayerService();
viewModel.EmpGoals = dlSvc.GetEmpGoalList(id.Value);
服务层方法:
public List<EmployeeGoal> GetEmpGoalList(int empID)
{
//Get employee info
var empInfo = db.Employees.Where(x => x.ID == empID).Select(x => new { ID = x.ID, LastName = x.LastName, Firstname = x.FirstName }).FirstOrDefault();
//Get initial bottom tier list of employee goals
List<int> goalIdList = db.EmployeeMaps.Where(x => x.EmployeeID == empID).Select(x => x.GoalID).ToList();
List<EmployeeGoal> empGoalList = new List<EmployeeGoal>();
List<int> usedGoalList = new List<int>();
foreach (var goal in goalIdList)
{
var tempID = goal;
while (tempID != 0 && tempID != null)
{
var gmData = (from g in db.Goals
join m in db.EmployeeMaps.Where(m => m.EmployeeID == empInfo.ID) on g.ID equals m.GoalID into m_g
from mg in m_g.DefaultIfEmpty()
where g.Goals == tempID
select new EmployeeGoal
{
EmployeeID = empInfo.ID,
LastName = empInfo.LastName,
FirstName = empInfo.FirstName,
GoalID = g.ID,
Name = g.Name,
ParentID = g.ParentID,
Parent = g.Parent,
WeightPct = (mg == null) ? 0 : mg.WeightPct,
Locked = (mg == null) ? 0 : mg.State.Equals(1),
Activities = g.Activities
}).FirstOrDefault();
if (!usedGoalList.Contains(gmData.GoalID))
{
empGoalList.Add(gmData);
UsedGoalList.Add(gmData.GoalID);
}
tempID = gmData.ParentId;
}
}
return empGoalList;
}
代码是我的头顶未经测试,因此可能无法按原样运行。如果需要,您还可以添加一些元数据来确定每个目标的“层级”,如果您需要从根向下排序目标列表或类似的东西。此解决方案也可能无法正常工作,因为它比单个LINQ查询效率低得多,因为这个查询有多个命中数据库。要保存数据库命中,您还可以先在内存中构建表,然后从那些表中查询(如果是首选)。
希望它有助于或至少为可行的解决方案提供一些想法。