简体   繁体   English

嵌套的Linq查询(多个级别)

[英]Nested Linq query (multiple levels)

How can I put the following loops into one Linq query? 如何将以下循环放入一个Linq查询中? The end result that I am trying to achieve is getting a list of Statements that are in those class methods. 我试图实现的最终结果是获取这些类方法中的Statements列表。

Context: For every class, the corresponding methods are fetched with the classname. 上下文:对于每个类,都使用类名获取相应的方法。 With every combination of classname / method name, I can call the metadata to get the source code (string). 通过类名/方法名的每种组合,我可以调用元数据来获取源代码(字符串)。 Then I compile that string and that Results in Method object that has and IEnumerable containing all of the code statements of that method. 然后,我编译该字符串,并在Method对象中编译具有IEnumerable的结果对象,其中IEnumerable包含该方法的所有代码语句。 So I was to get the list of statements across all classes and methods. 所以我要获得所有类和方法的语句列表。

        IXppcMetadataProvider serviceMetadataProvider = Program.getXppcMetadataProvider();

        IEnumerable<string> classNames = serviceMetadataProvider.ClassNames();

        MultipassAdministrator multipassAdmin = new MultipassAdministrator(serviceMetadataProvider);


        foreach (string className in classNames)
        {
            IEnumerable<string> classMethods = serviceMetadataProvider.ClassMethods(className);

            foreach (string methodName in classMethods)
            {
                string source = serviceMetadataProvider.GetClassMethodSource(className, methodName);

                Method method = multipassAdmin.CompileSingleMethod(source) as Method;

                if (method != null)
                {
                    foreach (Statement statement in method.Statements)
                    {
                        System.Console.WriteLine(statement.ToString());
                    }
                }
            }
        }

Basically you need to use the following Linq methods that act like higher order functions 基本上,您需要使用以下类似于高级函数的 Linq方法

System.Console.WriteLine(
    String.Join(Environment.NewLine,
                getXppcMetadataProvider().ClassNames().SelectMany(
                    className => getXppcMetadataProvider().ClassMethods(className)
                    .Select(
                        methodName => getXppcMetadataProvider()
                        .GetClassMethodSource(className, methodName)
                    ).Select(
                        source => new MultipassAdministrator(getXppcMetadataProvider())
                        .CompileSingleMethod(source) as mymeth)
                )
                .Where(method => method != null).SelectMany(
                    method => method.Statements
                ).Select(statement => statement.ToString())

               ));

Select when you have a 1 to 1 correspondence, as opposite to SelectMany , that would correspond to bind in Haskell. Select当你有一个1对1的对应关系,因为对面SelectMany ,将对应于bind在Haskell。

Notice that is straightforward to get function composition in Linq, as shown above. 注意,如上所示,在Linq中获得函数组合很简单。

Converting to the query syntax is easier, but LINQ is slower and harder to debug/comprehend. 转换为查询语法更容易,但是LINQ速度较慢,调试/理解也较难。

var q = from nothing in new[] { 0 }
        let serviceMetadataProvider = Program.getXppcMetadataProvider()
        let classNames = serviceMetadataProvider.ClassNames()
        let multipassAdmin = new MultipassAdministrator(serviceMetadataProvider)

        from className in classNames
        let classMethods = serviceMetadataProvider.ClassMethods(className)

        from methodName in classMethods
        let source = serviceMetadataProvider.GetClassMethodSource(className, methodName)
        let method = multipassAdmin.CompileSingleMethod(source) as Method
        where method != null

        from statement in method.Statements
        select statement.ToString();

System.Console.WriteLine(String.Join(Environment.NewLine, q));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM