使用LINQ从派生的子对象集合中检索信息

时间:2014-10-23 20:21:07

标签: linq collections children

我一直在尝试获取Office ID包含在某个列表中的办事处的所有工作流程列表。我可以很容易地获得具有SingleWorkflowSteps的所有工作流,因为它们只有一个Office,但是我无法理解如何成功获取MultiWorkflowStep中包含的那些。所有工作流程步骤都包含SingleWorkflowStep或包含两个或更多SingleWorkflowSteps的MultiWorkflowStep。在我设计这个时,这似乎是一种合乎逻辑的方式,但是我的LINQ-fu并没有我想象的那么好。有人可以指出我正确的方向。代码如下:

var OfficesToFind = new List<int> (new int[] { 1,3,5,7,9,10,11,12} );


public class Workflow
{
    public Workflow()
    {
        WorkflowSteps = new List<WorkflowStepBase>();
    }

    public int Id { get; set; }
    public virtual ICollection<WorkflowStepBase> WorkflowSteps { get; set; }
}

public abstract class WorkflowStepBase
{
    public int Id { get; set; }
    public int StatusId { get; set; }
    public virtual Workflow Workflow { get; set; }

    public virtual Status Status { get; set; }        
}

public class MultiWorkflowStep : WorkflowStepBase
{
    public MultiWorkflowStep()
    {
        ChildSteps = new List<SingleWorkflowStep>();
    }

    public virtual ICollection<SingleWorkflowStep> ChildSteps { get; set; }
}

public class SingleWorkflowStep : WorkflowStepBase
{
    public int? ParentStepId { get; set; }
    public int OfficeId { get; set; }

    public virtual MultiWorkflowStep ParentStep { get; set; }
    public virtual Office Office { get; set; }
}

public class Office
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class WorkflowService : IWorkflowService<Workflow>
{
    private readonly IRepository<Workflow> _workflowService;
    private readonly IRepository<SingleWorkflowStep> _singleStepService;
    private readonly IRepository<MultiWorkflowStep> _multiStepService;

    public WorkflowService(IUnitOfWork uow)
    {
        _workflowService = uow.GetRepository<Workflow>();
        _singleStepService = uow.GetRepository<SingleWorkflowStep>();
        _multiStepSercice = uow.GetRepository<MultiWorkflowStep>();
    }

    // ~ ------- Other CRUD methods here -------- ~

    public IEnumerable<Workflow> GetWorkflowFilter(List<int> statuses, List<int> offices...)
    {
        var query = _workflowService.GetIQueryable(); // returns an IQueryable of dbset

        if(statuses.Any())
        {
            query = query.Where(q => statuses.Contains(q.StatusId));
        }

        if(offices.Any())
        {
            // Get all active single steps and the ones that contain the offices
            singleSteps = _singleStepService
                .Where(s => s.StatusId == (int)Enumerations.StepStatus.ACTIVE)
                .Where(s => offices.Contains(s.OfficeId));  

            // Get all of the parent Workflows for the singleSteps
            var workflows = singleSteps.Select(w => w.Workflow);

            // Update the query with the limited scope
            query = query.Where(q => q.Workflow.Contains(q));
        }
        return query.ToList();
    }
}

1 个答案:

答案 0 :(得分:0)

好吧,经过一夜好眠,全都眼睛发亮,浓密的尾巴,我想出了自己的问题。首先,更新的代码都错了。因为每个派生的WorkflowStep都可以访问工作流,并且每个MultiWorkflowStep都包含SingleWorkflowSteps列表 - 当我获得所有SingleWorkflowSteps(包括所有来自MultiWorkflowStep)的列表时,我只需要获取所有父项的列表SingleWorkflowSteps的工作流程。接下来,我更新了我的查询以限制新工作流列表中包含的工作流,这里是GetWorkflowFilter方法的正确代码:

...
    if(offices.Any())
    {
        // Get all active single steps and the ones that contain the offices
        singleSteps = _singleStepService.Where(s => s.StatusId == (int)Enumerations.StepStatus.ACTIVE).Where(s => offices.Contains(s.OfficeId));  

        // Get all of the parent Workflows for the singleSteps
        var workflows = singleSteps.Select(w => w.Workflow);

        // Update the query with the limited scope
        query = query.Where(q => q.Workflow.Contains(q));
    }
    return query.ToList();
}