如何使用具体类进行多个分组?

时间:2012-03-22 18:37:21

标签: c# .net linq nhibernate group-by

我有这种情况。

我想要国家和类别的小组。

A store can have many countries and a country can have many stores. (many to many)
A store can have many categories and a category can have many stores (many to many)

说我有这些类别

Food
Gas
Car Shop

我有这些商店

Pizza Hut
Canadian Tire
Shell

我有这些国家

Canada
USA

所以最后看起来应该是这样的

Canada
 Food
   Pizza Hut
 Gas
  Canadian Tire (some places have gas stations)
  Shell
 Car Shop
  Canadian Tire
USA
  Food
    Pizza Hut
  Gas
   Shell
  Car Shop
   (nothing in my example as Canadian Tire is only in Canada)

以上几乎是我想向用户展示的最终结果。我现在被困在linq中分组(我也在使用nhibernate)

 session.Query<Store>().FetchMany(x => x.Countries).FetchMany(x => x.Categories).GroupBy(x => new {x.Countires, x.Categories})

上面会给我一个匿名类,但我需要从服务层返回结果,然后使用它们来创建我的视图模型。

所以我不能使用匿名类。

我不确定如何进行具体的课程?

它需要像Igrouping那样吗?

2 个答案:

答案 0 :(得分:2)

如果定义一个类,那么具有正确属性和适当构造函数的MyClass可以在查询中使用新的MyClass(x.Countries,x.Categories)而不是匿名类型构造函数。

或者你可以使用没有参数的默认构造函数,并使用普通的C#属性初始化语法。我的手机不会做大括号,所以我无法发布代码片段: - (

答案 1 :(得分:0)

您将获得一个匿名类,因为您使用的是GroupBy方法。 IQueryable中的GroupBy几乎与SQL GROUP BY子句一样。为了更好地理解分组,您必须考虑SQL GROUP BY可以与多对一运算符一起使用,例如SUMAVGMAXMIN,因为它们从行集返回单个结果。在我看来,你的“分组”概念是GUI上的可视化分组。

选择所有人(姓名,姓氏)和GROUP BY姓氏是没有意义的,因为在最终结果上投影的名称的选择是不明确的。

GroupBy运算符正是您不想使用的。如果你正确地建立了多对多+多对一关系(形成多对多关系)那么你应该有类似的东西

public class Country{

    Store[] stores;
}

public class Store {
    Category[] categories;
    Country[] countries;
}

public class Category {
    Store[] stores;
}

“分组”值的最佳方法是使用普通的旧for循环。这是 pseuso-C#代码

for (Country co in session.Query<Country>()) {
    Console.WriteLine(co); //Possibly c.Name or whatever
    Console.Indentation++; //.NET has not such a method but you understand what it means
    for (Category ca in co.Categories) {
        Console.WriteLine(ca);
        Console.Indentation++;
        for (Store s in ca.Stores) {
            Console.WriteLine(s);
        }
        Console.Indentation--;
    }
    Console.Indentation--;
}

[添加]反向查找的示例,如果您的模型表明存在引用类别 - >国家但不包含国家/地区&gt;类别

,则适用
   for (Country co in session.Query<Country>()) {
        Console.WriteLine(co);
        Console.Indentation++;
        for (Category ca in session.Query<Category>().Where(x => x.Country.equals(co))) {
            Console.WriteLine(ca);
            //snip
        }
        Console.Indentation--;
    }