2014-02-19 5 views
0

Во-первых, я искал некоторые советы о том, как выполнять групповое соединение на основе функции, а не равенство двух ключей.Выполнение GroupJoin с использованием Linq на основе функции

Во-вторых, в моем реальном приложении Ресурсы (массив строк) загружаются из файла. Я не хочу загружать их каждый раз, когда перечисляю последовательность. Я надеялся создать функцию, которая позволила бы отсрочить исполнение.

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 

ответ

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); 
     } 
    } 
} 
Смежные вопросы