Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用具有树结构的LINQ_C#_Linq_Entity Framework_Lambda - Fatal编程技术网

C# 使用具有树结构的LINQ

C# 使用具有树结构的LINQ,c#,linq,entity-framework,lambda,C#,Linq,Entity Framework,Lambda,我使用EF和Linq从数据库返回值。我有一个文件夹结构,文件夹可以包含文件夹列表或设备列表。我想要的是能够构建一个所有设备s的列表,这些设备位于(或位于)一个文件夹中,包括属于该文件夹的任何文件夹(假设我想要查看顶级目录中的所有文件,其中也包括子目录) 这里真正重要的是可能有很多设备,所以我需要分页,所以理想情况下这一切都可以用LINQ完成,这样我可以在返回结果集之前对查询进行排序和分页 这是我的设置的基本版本(为了简单起见,删除了键、注释和其他内容) 公共类文件夹 { 公共虚拟ICollect

我使用EF和Linq从数据库返回值。我有一个
文件夹
结构,文件夹可以包含
文件夹
列表或
设备
列表。我想要的是能够构建一个所有
设备
s的列表,这些设备位于(或位于)一个文件夹中,包括属于该文件夹的任何文件夹(假设我想要查看顶级目录中的所有文件,其中也包括子目录)

这里真正重要的是可能有很多设备,所以我需要分页,所以理想情况下这一切都可以用LINQ完成,这样我可以在返回结果集之前对查询进行排序和分页

这是我的设置的基本版本(为了简单起见,删除了键、注释和其他内容)

公共类文件夹
{
公共虚拟ICollection子项{get;set;}
公共虚拟ICollection设备{get;set;}
}
//这是我目前拥有的只返回1个文件夹的函数
//需要以某种方式扩展以返回其下所有文件夹的设备
函数GetFolderDevices(int-folderId、分页选项选项)
{
//获取所有文件夹和设备
使用(var dbObj=this.context.CreateDBContext())
{
EMDB.Models.Folder Folder=dbObj
.通讯录
.Include(a=>a.Devices.Select(d=>d.Settings))
.FirstOrDefault(f=>f.FolderId==FolderId);
//在此处应用分页(已处理)
}
}

我相信您可以使用迭代器。像这样的事情可能会奏效:

    static IEnumerable<Folder> Descendants(Folder root)
    {
        var nodes = new Stack<Folder>(new[] { root });
        while (nodes.Any())
        {
            Folder node = nodes.Pop();
            yield return node;
            foreach (var n in node.Children) nodes.Push(n);
        }
    }

在数据库中使用公共表表达式准备视图,并将其映射到EF。不确定该怎么做?怎么做?您可以像表一样轻松地将视图映射到EF,但您必须记住,使用该映射可能无法插入/更新。我不确定的是(视图,映射它,它意味着什么?)我会为此使用递归函数-主要是因为它(在我看来)使代码更具可读性。据我所知,您可以这样做:这里唯一的问题是调试,当您遇到堆栈溢出以外的异常时。在每个深度上都没有局部变量的调用堆栈和状态。对于更简单的逻辑,它是可读的,您只是在迭代,但是当您有更多的条件要计算时,它就变得很困难了。您如何知道当前迭代的深度?尝试打印缩进等于深度的树,看看代码有多脏。我认为另一个问题是我完全没有回答眼前的问题(我写了上面的答案)。此解决方案仍将在C#类中进行排序和分页。似乎我急于写答案,而不是阅读和理解问题-对不起。@Ykok太好了,你相信我,这是一些正确的方式
    static IEnumerable<Folder> Descendants(Folder root)
    {
        var nodes = new Stack<Folder>(new[] { root });
        while (nodes.Any())
        {
            Folder node = nodes.Pop();
            yield return node;
            foreach (var n in node.Children) nodes.Push(n);
        }
    }
    // This is the function I currently have that only returns 1 folder
    // needs to somehow be expanded to return devices for all folders beneath it too
    function GetFolderDevices(int folderId, PaginationOptions options)
    {
            // Get all folders and devices
            using (var dbObj = this.context.CreateDBContext())
            {
                    EMDB.Models.Folder folder = dbObj
                            .AddressBook
                            .Include(a => a.Devices.Select(d => d.Settings))
                            .FirstOrDefault(f => f.FolderId == folderId);

                    var result = from fold in Descendants(folder)
                                 select fold;
                    // apply pagination here (already taken care of)
            }
    }