通过LINQ递归选择? [英] Recursive select via LINQ?

查看:137
本文介绍了通过LINQ递归选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  

可能重复:
  的LINQ to SQL递归查询

我被困具有建立通过LINQ递归选择自我引用表。

我使用这个类:

 公共类DivisionHierarchy
{
    公共事业部事业部{获得;组; }
    公开的IEnumerable< D​​ivisionHierarchy>司{获得;组; }
}
 

和我创造了这个功能,但不知何故,它是无限的。

 公开的IEnumerable< D​​ivisionHierarchy> GetDivisionHierarchy(IEnumerable的<科> allDivisions,司parentDivision)
{
    GUID? parentDivisionId = NULL;

    如果(parentDivision!= NULL)
         parentDivisionId = parentDivision.DivisionID;

    VAR childDivisions = allDivisions.Where(E => e.DivisionID == parentDivisionId);

    收藏< D​​ivisionHierarchy>等级=新的集合< D​​ivisionHierarchy>();

    的foreach(在childDivisions VAR格)
       hierarchy.Add(新DivisionHierarchy(){司= DIV,司= GetDivisionHierarchy(allDivisions,DIV)});

     返回层次;
}
 

任何线索,我可以开始?

感谢您!

P.S。是否有任何其他的方式来做到这一点?


根据 http://www.scip.be/index.php最新通报?页= ArticlesNET18#AsHierarchy

我发现我的错误。

有两件事情来实现: 1.根节点应数据库下创建的。

  1. 我改变code一点点。

     的Guid divisionID = Guid.Parse(5b487b3d-e9be-413F-b611-2fd7491e0d0d); //硬codeD不知何故
    变种rootDivision = db.Divisions.Where(ⅰ=> i.ID == divisionID).FirstOrDefault();
    变种divisionHierarchy = GetDivisionHierarchy(db.Divisions.AsEnumerable(),rootDivision);
     

    ...

     公开的IEnumerable< D​​ivisionHierarchy> GetDivisionHierarchy(IEnumerable的<科> allDivisions,司parentDivision)
            {
                GUID? parentDivisionId = NULL;
    
                如果(parentDivision!= NULL)
                    parentDivisionId = parentDivision.ID;
    
                VAR childDivisions = allDivisions.Where(司=> division.DivisionID == parentDivisionId);
    
                收藏< D​​ivisionHierarchy>等级=新的集合< D​​ivisionHierarchy>();
    
                的foreach(在childDivisions VAR格)
                {
                    DivisionHierarchy divisionHierarchy =新DivisionHierarchy();
                    divisionHierarchy.Division = DIV;
                    divisionHierarchy.Divisions = GetDivisionHierarchy(allDivisions,DIV);
                    hierarchy.Add(divisionHierarchy);
                }
    
                返回层次;
            }
     

解决方案

我会加载部门在非递归的方式,然后设置在code中的递推关系。下面是一个例子,它做到这一点的一个偷懒的办法

 公共类科
{
    公众诠释ID {获得;组; }
    公众诠释DivisionID {获得;组; }
    公共字符串名称{;组; }
    公共字符串描述{获得;组; }

    私有静态列表<科> _divisions;
    公共静态列表<科>司
    {
        得到
        {
            如果(_divisions == NULL){
                LoadAndSetUpDivisionsHierarchy();
            }
            返回_divisions;
        }
    }

    私有静态字典< INT,司> _divisionsByID;
    公共静态字典< INT,司> DivisionsByID
    {
        得到
        {
            如果(_divisionsByID == NULL){
                LoadAndSetUpDivisionsHierarchy();
            }
            返回_divisionsByID;
        }
    }

    私有静态司_root;
    公共静态科根
    {
        得到
        {
            如果(_root == NULL){
                LoadAndSetUpDivisionsHierarchy();
            }
            返回_root;
        }
    }

    私人部门_parentDivision;
    公共事业部ParentDivision
    {
        得到
        {
            如果(_parentDivision == NULL和放大器;&安培;!DivisionID = 0){
                _parentDivision = DivisionsByID [DivisionID]

            }
            返回_parentDivision;
        }
    }

    私人列表<科> _subDivisions =新的名单,其中,司>();
    公开名单<科>细分
    {
        {返回_subDivisions; }
    }

    私有静态无效LoadAndSetUpDivisionsHierarchyHierarchy()
    {
        //将部门使用LINQ非递归的方式
        //(细节这里没有显示)。
        _divisions = LoadDivisions();

        //添加师在字典中以ID
        _divisionsByID =新字典< INT,司>(_ divisions.Count);
        的foreach(司_divisions师){
            _divisionsByID.Add(division.ID,司);
        }

        //定义子部门和根分工
        的foreach(司_divisions师){
            如果(division.DivisionID == 0){
                _root =分裂;
            }否则,如果(division.ParentDivision!= NULL){
                division.ParentDivision.SubDivisions.Add(师);
            }
        }
    }

    私有静态列表<科> LoadDivisions()
    {
        抛出新的NotImplementedException();
    }
}
 

Possible Duplicate:
linq to sql recursive query

I got stuck with having to build a Recursive select via LINQ for the self referencing table.

I use this class:

public class DivisionHierarchy
{
    public Division Division { get; set; }
    public IEnumerable<DivisionHierarchy> Divisions { get; set; }
}

and I created this function but somehow it is infinite.

public IEnumerable<DivisionHierarchy> GetDivisionHierarchy(IEnumerable<Division> allDivisions, Division parentDivision)
{
    Guid? parentDivisionId = null;

    if (parentDivision != null)
         parentDivisionId = parentDivision.DivisionID;

    var childDivisions = allDivisions.Where(e => e.DivisionID == parentDivisionId);

    Collection<DivisionHierarchy> hierarchy = new Collection<DivisionHierarchy>();

    foreach (var div in childDivisions)
       hierarchy.Add(new DivisionHierarchy() { Division = div, Divisions = GetDivisionHierarchy(allDivisions, div) });

     return hierarchy;
}

Any clue where I can start?

Thank you!

P.S. Are there any others ways to do it?


UPDATES based on http://www.scip.be/index.php?Page=ArticlesNET18#AsHierarchy

I found my errors.

There are 2 things to implement: 1. The root node should be created under the database.

  1. I changed code a little bit.

    Guid divisionID = Guid.Parse("5b487b3d-e9be-413f-b611-2fd7491e0d0d"); // Hardcoded somehow
    var rootDivision = db.Divisions.Where(i => i.ID == divisionID).FirstOrDefault();
    var divisionHierarchy = GetDivisionHierarchy(db.Divisions.AsEnumerable(), rootDivision);
    

    ...

     public IEnumerable<DivisionHierarchy> GetDivisionHierarchy(IEnumerable<Division> allDivisions, Division parentDivision)
            {
                Guid? parentDivisionId = null;
    
                if (parentDivision != null)
                    parentDivisionId = parentDivision.ID;
    
                var childDivisions = allDivisions.Where(division => division.DivisionID == parentDivisionId);
    
                Collection<DivisionHierarchy> hierarchy = new Collection<DivisionHierarchy>();
    
                foreach (var div in childDivisions)
                {
                    DivisionHierarchy divisionHierarchy = new DivisionHierarchy();
                    divisionHierarchy.Division = div;
                    divisionHierarchy.Divisions = GetDivisionHierarchy(allDivisions, div);
                    hierarchy.Add(divisionHierarchy);
                }
    
                return hierarchy;
            }
    

解决方案

I would load the divisions in an non-recursive way and then set up the recursive relations in code. Here is an example, which does this in a lazy way

public class Division
{
    public int ID { get; set; }
    public int DivisionID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }

    private static List<Division> _divisions;
    public static List<Division> Divisions
    {
        get
        {
            if (_divisions == null) {
                LoadAndSetUpDivisionsHierarchy();
            }
            return _divisions;
        }
    }

    private static Dictionary<int, Division> _divisionsByID;
    public static Dictionary<int, Division> DivisionsByID
    {
        get
        {
            if (_divisionsByID == null) {
                LoadAndSetUpDivisionsHierarchy();
            }
            return _divisionsByID;
        }
    }

    private static Division _root;
    public static Division Root
    {
        get
        {
            if (_root == null) {
                LoadAndSetUpDivisionsHierarchy();
            }
            return _root;
        }
    }

    private Division _parentDivision;
    public Division ParentDivision
    {
        get
        {
            if (_parentDivision == null && DivisionID != 0) {
                _parentDivision = DivisionsByID[DivisionID];

            }
            return _parentDivision;
        }
    }

    private List<Division> _subDivisions = new List<Division>();
    public List<Division> SubDivisions
    {
        get { return _subDivisions; }
    }

    private static void LoadAndSetUpDivisionsHierarchyHierarchy()
    {
        // Load the divisions in a non-recursive way using LINQ
        // (details not shown here).
        _divisions = LoadDivisions();

        // Add the divisions in a dictionary by id
        _divisionsByID = new Dictionary<int, Division>(_divisions.Count);
        foreach (Division division in _divisions) {
            _divisionsByID.Add(division.ID, division);
        }

        // Define sub-divisions and root division
        foreach (Division division in _divisions) {
            if (division.DivisionID == 0) {
                _root = division;
            } else if (division.ParentDivision != null) {
                division.ParentDivision.SubDivisions.Add(division);
            }
        }
    }

    private static List<Division> LoadDivisions()
    {
        throw new NotImplementedException();
    }
}

这篇关于通过LINQ递归选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆