富国沪深
使用Linq是绝对不变的要求吗?为什么需要在单个查询中将其返回?建议:使用SQL。它可以在一个单一的查询做,但你不会喜欢的查询。我假设使用SQL Server(可以对其他DBMS进行不同的处理)。WITH V AS ( SELECT DISTINCT V.* FROM Orders O CROSS APPLY ( VALUES (1, O.Products), (2, O.Categories), (3, O.Subcategories) ) V (Which, Value)),Nums AS ( SELECT Num = Row_Number() OVER (PARTITION BY V.Which ORDER BY V.Value), V.Which, V.Value FROM V)SELECT Products = P.[1], Categories = P.[2], Subcategories = P.[3]FROM Nums N PIVOT (Max(N.Value) FOR N.Which IN ([1], [2], [3])) P;看到此工作在db <> fiddle输出:Products Categories Subcategories-------- ---------- -------------prod1 cat1 sub1prod2 cat2 sub2prod5 cat3 sub3prod8 cat7 sub6null null sub8如果您被束缚并决心使用Linq,那么我将无法为您提供查询样式的语法。我只知道C#代码样式的语法,但是这是一个刺脚。不幸的是,我认为这不会为您带来任何好处,因为我不得不使用一些非常时髦的东西来使其工作。它使用与上面的SQL查询基本相同的技术,只是,PIVOTLinq中没有等效的技术,除了自定义类之外,没有真正的自然行对象。using System;using System.Collections.Generic;using System.Linq;public class Program { public static void Main() { var data = new List<Order> { new Order("prod1", "cat1", "sub1"), new Order("prod1", "cat2", "sub2"), new Order("prod2", "cat3", "sub6"), new Order("prod1", "cat1", "sub1"), new Order("prod5", "cat2", "sub8"), new Order("prod2", "cat1", "sub1"), new Order("prod1", "cat7", "sub3"), new Order("prod8", "cat2", "sub2"), new Order("prod2", "cat3", "sub1") }; int max = 0; var items = data .SelectMany(o => new List<KeyValuePair<int, string>> { new KeyValuePair<int, string>(1, o.Products), new KeyValuePair<int, string>(2, o.Categories), new KeyValuePair<int, string>(3, o.Subcategories) }) .Distinct() .GroupBy(d => d.Key) .Select(g => { var l = g.Select(d => d.Value).ToList(); max = Math.Max(max, l.Count); return l; }) .ToList(); Enumerable .Range(0, max) .Select(i => new { p = items[0].ItemAtOrDefault(i, null), c = items[1].ItemAtOrDefault(i, null), s = items[2].ItemAtOrDefault(i, null) }) .ToList() .ForEach(row => Console.WriteLine($"p: {row.p}, c: {row.c}, s: {row.s}")); }}public static class ListExtensions { public static T ItemAtOrDefault<T>(this List<T> list, int index, T defaultValue) => index >= list.Count ? defaultValue : list[index];}public class Order { public Order(string products, string categories, string subcategories) { Products = products; Categories = categories; Subcategories = subcategories; } public string Products { get; set; } public string Categories { get; set; } public string Subcategories { get; set; }}我想我们可以交换一下.Select(i => new { p = items[0].ItemAtOrDefault(i, null), c = items[1].ItemAtOrDefault(i, null), s = items[2].ItemAtOrDefault(i, null)})为了这:.Select(i => new Order( items[0].ItemAtOrDefault(i, null), items[1].ItemAtOrDefault(i, null), items[2].ItemAtOrDefault(i, null)))然后在输出部分中使用该类的属性。