Как сделать несколько группировок с конкретным классом? - PullRequest
0 голосов
/ 22 марта 2012

У меня есть этот сценарий.

Я хочу группу по стране и категории.

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})

Вышесказанное вернет мне анонимный класс, но мне нужно вернуть результаты из сервисного уровня, а затем использовать их для создания моего представления Модель.

Так что я не могу использовать анонимный класс.

Я не уверен, как сделать мой конкретный класс?

Должно ли это быть как группировка или что-то там?

Ответы [ 2 ]

2 голосов
/ 22 марта 2012

Если вы определяете класс, скажем, MyClass, с правильными свойствами и соответствующим конструктором, вы можете просто использовать новый MyClass (x.Countries, x.Categories) в своем запросе вместо конструктора анонимного типа.

Или вы можете просто использовать конструктор по умолчанию без параметров и использовать обычный синтаксис инициализации свойства C #. Мой телефон не будет использовать фигурные скобки, поэтому я не могу опубликовать фрагмент кода: - (

0 голосов
/ 22 марта 2012

Вы получаете анонимный класс, потому что вы используете метод GroupBy . GroupBy в IQueryable работает почти как предложение SQL GROUP BY. Чтобы лучше понять группировку, вы должны учитывать, что SQL GROUP BY может использоваться только с такими операторами типа "многие к одному", как SUM, AVG, MAX, MIN, поскольку они возвращают один результат из набора строк. Ваша концепция "группировки", на мой взгляд, визуальная группировка в графическом интерфейсе.

Нет смысла выбирать всех людей (имя, фамилию) и GROUP BY фамилию, потому что выбор имени для проецирования на конечный результат неоднозначен.

Оператор GroupBy - это именно то, что вы не хотите использовать. Если вы правильно установили отношение «многие к одному + многие к одному» (которое образует многие ко многим), то у вас должно быть что-то вроде

public class Country{

    Store[] stores;
}

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

public class Category {
    Store[] stores;
}

Лучший способ "сгруппировать" значения - использовать простые старые циклы for. Вот псевдо-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--;
}

[Добавить] пример обратного просмотра, который применяется, если ваша модель говорит, что есть ссылка Категория-> Страна, но не Страна-> Категория

   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--;
    }
...