Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/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
这个LINQ的方法语法是什么,它是连接吗?如果不是,它是什么?_Linq - Fatal编程技术网

这个LINQ的方法语法是什么,它是连接吗?如果不是,它是什么?

这个LINQ的方法语法是什么,它是连接吗?如果不是,它是什么?,linq,Linq,我发现自己在LINQ中使用了这种模式: class Thing { public int ID { get; set; } public int ColorID { get; set; } } class Color { public int ID { get; set; } public string Description { get; set; } } static vo

我发现自己在LINQ中使用了这种模式:

    class Thing
    {
        public int ID { get; set; }
        public int ColorID { get; set; }
    }
    class Color
    {
        public int ID { get; set; }
        public string Description { get; set; }
    }
    static void Main()
    {
        var things = new List<Thing> { new Thing { ID = 1, ColorID = 1 }, new Thing { ID = 2, ColorID = 1 }, new Thing { ID = 3, ColorID = 2 }, new Thing { ID = 4, ColorID = 1 } };
        var colors = new List<Color> { new Color { ID = 1, Description = "red" }, new Color { ID = 2, Description = "green" }, new Color { ID = 3, Description = "blue" } };
        var joined = (from thing in things
                      from color in colors
                      where thing.ColorID == color.ID
                      select new { ID = thing.ID, Color = color.Description }).ToArray();
        foreach (var thing in joined)
        {
            Console.WriteLine("(" + thing.ID + ", " + thing.Color + ")");
        }
        //Writes:
        //(1, red)
        //(2, red)
        //(3, green
        //(4, red)
    }
它的核心,四行查询语法,感觉非常像我可能在tSQL中编写的内部连接,但是当我看到它们使用JOIN这个词时,上面的LINQ没有


上面的LINQ正在执行的“连接”是什么?我将如何用LINQ方法语法重写它

就LINQ理解而言,它根本不执行连接。它只是基于两个属性进行过滤,其中一个恰好来自一个范围变量,另一个恰好来自另一个范围变量。在方法语法中,您可以这样写:

var joined = things.SelectMany(thing => colors,
                               (thing, color) => new { thing, color })
                   .Where(pair => pair.thing.ColorID == pair.color.ID)
                   .Select(pair => new { ID = pair.thing.ID,
                                         Color = pair.color.Description })
                   .ToArray();
这里的对是编译器自动引入的透明标识符。这不是由于where中的筛选,而是由于具有多个from子句。。。第一个from子句之后的每个from子句都使用SelectMany,并引入一个透明标识符,允许您引用多个范围变量thing和color,这些变量组成一个单独的对象,以便管道的每个阶段仅在概念上处理一个值

请注意,当您有两个from子句时:

。。。这就像笛卡尔连接。。。但是LINQ允许一些更微妙的东西,例如:

from person in people
from book in person.Books

换句话说,第二序列可以取决于第一序列的当前值。管道的任何后续阶段,例如,其中或select作用于每一对:一个来自第一个序列,然后一个来自第一个序列中的元素生成的第二个序列。

谢谢John。我从专门编写查询语法开始LINQ,但最近我一直在切换到方法语法,因为它通常更清晰、更像C,但在本例中,虽然它确实有助于解释发生了什么,但它不那么简单。我正要回答它执行内部循环联接。语法非常类似于在SQL-89中编写内部联接的方式。但你说它不是。@Magnus:它可能会被LINQ转换成一个内部循环连接到SQL,当然…@JonSkeet,但这是LINQ到对象。但是不能说循环连接是在这里执行的。与使用实际连接语法时的散列连接相比?@dumbledad:这两种类型绝对值得熟悉。就我个人而言,我倾向于使用方法语法,除非涉及到透明标识符——在这一点上,查询表达式最终会变得更简单。
from person in people
from book in person.Books