基于函数使用Linq执行GroupJoin

时间:2014-02-19 04:36:11

标签: c# linq

首先,我正在寻找一些关于如何基于函数而不是两个键相等来执行组连接的建议。

其次,在我的实际应用程序中,从文件加载Resources(一个字符串数组)。我不想在每次枚举序列时加载这些。我希望创建一个允许延迟执行的函数。

var files = new[]
{
    new { Name = "A", Resources = new[] { "A.1", "A.2" } }, 
    new { Name = "B", Resources = new[] { "B.1", "B.2" } }
};

var resources = new[] 
{ 
    new { File = "A", Resources = new[] {"C", "D"} },
    new { File = "B", Resources = new[] {"E", "F"} },
    new { File = "A.1", Resources = new[] {"C.1", "D.1"} },
    new { File = "A.2", Resources = new[] {"C.2", "D.2"} },
    new { File = "B.1", Resources = new[] {"E.1", "F.1"} },
    new { File = "B.2", Resources = new[] {"E.2", "F.2"} },
};

foreach (var file in files)
{
    Console.WriteLine("File {0}", file.Name);

    var fileResources = resources.Where(r => r.File == file.Name).SelectMany(r => r.Resources);                    
    var childResources = file.Resources.SelectMany(c => resources.Where(r => r.File == c).SelectMany(r => r.Resources));

    // How can we perform a group join using c.StartsWith(t)
    var groupedResources = fileResources.GroupJoin(childResources, t => t, c => c, (p, c) => new { Parent = p, Children = c });
    foreach (var grouping in groupedResources)
    {
        Console.WriteLine("{0}", grouping.Parent);
        foreach (var child in grouping.Children)
        {
            Console.WriteLine("\t{0}", child);
        }
    }
}

预期输出为

File A
C
    C.1
    C.2
D
    D.1
    D.2
File B
E
    E.1
    E.2
F
    F.1
    F.2

1 个答案:

答案 0 :(得分:0)

您可以使用group clause代替GropJoin这样的内容

foreach (var file in files)
{
    var groupedResources = from r in resources
                           join f in file.Resources on r.File equals f
                           from childResource in r.Resources

                           from fileResource in resources
                           from parentResource in fileResource.Resources
                           where fileResource.File == file.Name

                           group childResource by new { parentResource, IsStart = childResource.StartsWith(parentResource) } into g
                           where g.Key.IsStart
                           select new { Parent = g.Key.parentResource, Children = g };

    foreach (var grouping in groupedResources)
    {
        Console.WriteLine("{0}", grouping.Parent);
        foreach (var child in grouping.Children)
        {
            Console.WriteLine("\t{0}", child);
        }
    }
}