Steav
Steav

Reputation: 1486

Nested Linq Group By

What I have: List

Class: Rule --> Class: Term ---> Property Compare_Src Property Compare_Mode

What I want to do: use a Linq statement to get my Rules, grouped by a Combination of its Compare_Src and Compare_Mode.

Static Example for one Combination: (Here I get a list for all rules with Compare_src = EmpfaengerToken and Compare_mode = equals. What I want is a full list with all rules, grouped by the two propertys, instead of hardcoded values.

            var regeln_empfaengertoken  = 
        (
            from rule in rules 
            where 
            (
                from term in rule.Term 
                    where 
                    (
                        term.Compare_src == Entities.Enums.Compare_src.EmpfaengerToken
                        &&
                        term.Compare_mode.ToString() == "equals"
                    )
                    select term
            ).Count() > 0 
            select rule
        ).ToList<Entities.Rule>();

I know it's possible, but can't find the right solution :(

  [Serializable]
public class Rule
{
    private List<Term> _term = new List<Term>();
    ...
}


   [Serializable]
public class Term
{
    private Entities.Enums.Compare_src _compare_src;
    private Entities.Enums.Compare_mode _compare_mode;
    private Entities.Enums.Compare_Type _compare_type;
    .........
 }

Upvotes: 2

Views: 2261

Answers (5)

Variant
Variant

Reputation: 17385

Try something like this:

rules.SelectMany(rule => rule.Term)
     .GroupBy(term => new { term.Compare_src, term.Compare_mode })
     .Select(termGroup => 
           new {
              Key = termGroup.key, 
              Rules = rules.Where(r => r.Term.Any(t => 
                 t.Compare_src == termGroup.key.Compare_src && 
                 t.Compare_mode == termGroup.key.Compare_mode
              )
               }
             )

What I did here (tried anyway, didn't check if this actually works with your model) is to inverse the query. First get all the terms, group them by the mutiple field key and then select the relevant rules for each group.

Upvotes: 3

BrokenGlass
BrokenGlass

Reputation: 161012

Why doesn't a single group by suffice? You can group by multiple terms using an anonymous class:

var ruleGroups = from rule in rules 
                 group by new { rule.Term.Compare_src, rule.Term.Compare_mode } 
                 into g
                 select ...;

This would give you an IGrouping though that you can convert to a list of lists, you could flatten this structure using SelectMany():

var orderedRuleList = ruleGroups.SelectMany( x => x)
                                .ToList();

Upvotes: 2

Tomas Jansson
Tomas Jansson

Reputation: 23472

It's hard to know exactly what you want since the example is not quite so clear. Have you looked at these two resources? MSDN and 101 Linq examples.

If you are more precise in your question it would be easier to help you.

Upvotes: 0

Kelly Cline
Kelly Cline

Reputation: 2246

You might try

group term by new { term.Compare_src, term.Compare_mode }

Upvotes: 0

Sebastian Mach
Sebastian Mach

Reputation: 39109

Don't write write-only code. I know it is tempting to go off on this syntactic sugar for lambdas and extension methods, but I'd advice to assign intermediate results to temporary holders.

Upvotes: 0

Related Questions