LINQ + объединяет с вложенным выходом бритвы foreach, выписывая строки заголовков из groupby - PullRequest
2 голосов
/ 09 мая 2011

У меня есть базовая модель магазина.У меня есть Предметы, Предметы имеют категорию, а категории имеют меню.Я хочу составить список пунктов данного меню, сгруппированных по категориям элементов, чтобы он записал название категории, затем перечислил элементы под ним и перешел к следующей категории.Меня побеждает синтаксис.Пожалуйста, помогите.

Элементы:

public class Item
{
    public int ID { get; set; }
    public string Name { get; set; }
    public double Price { get; set; }
    public int Order { get; set; }
    public bool Active { get; set; }
    public Category Category { get; set; }
}

Категории:

public class Category
{
    public int ID { get; set; }
    public string Name { get; set; }
    public bool Active { get; set; }
    public int Order { get; set; }
    public Menu Menu { get; set; }
}

Меню:

public class Menu
{
    public int ID { get; set; }
    public string Name { get; set; }
    public bool Active { get; set; }
    public int Order { get; set; }
}

В контроллере у меня есть оператор linq:

    var model = from i in _db.Items
                join c in _db.Categories on i.Category.ID equals c.ID
                join m in _db.Menus on c.Menu.ID equals m.ID
                where m.Name == menuName
                select i;

Я почти уверен, что это не сработает с select i, но у меня нет идей, и это его текущее состояние.

В моем представлении:

@model IEnumerable<MyStore.Models.Item>

И я перепробовал все, что мог придумать, чтобы заставить работать группу, но ничего не получилось.Я даже попытался просто установить переменную в currentCategoryID и проверить, изменилось ли оно, а затем записать имя категории, но он выдает ошибку, когда нажимает @ item.Category.Name, говоря, что ссылка на объект не установлена ​​для экземпляра объекта.

Я полностью потерян.: (

ОБНОВЛЕНИЕ ОК, эта часть работает, теперь есть способ сделать этот цикл более элегантным? Мне не нравится temp var, чтобы проверить, является ли это новой категорией.

int currentCategory = 0;
    foreach (var item in Model)
    {

        if (!item.Category.ID.Equals(currentCategory))
        {
            <h3>@item.Category.Name</h3>
           currentCategory = item.Category.ID;
        }

        <div>
                @Html.DisplayFor(modelItem => item.Name)

            </div>
        <div>

        </div>
    }

1 Ответ

1 голос
/ 09 мая 2011

В целом ваш запрос выглядит хорошо и должен давать ожидаемые результаты - при условии, что у вас нет нулевых свойств для Menu или Category.

Может ли быть так, что некоторые из ваших категорий содержат нулевое свойство Menu? В этом случае ваше объединение вызовет исключение NullReferenceException, поскольку вы напрямую пытаетесь получить доступ к c.Menu.ID - обходной путь будет следующим:

var model = from i in Items
            join c in Categories on i.Category.ID equals c.ID
            where c.Menu !=null
            join m in Menus on c.Menu.ID equals m.ID
            where m.Name == menuName
            select i;

Та же проблема со свойством Category Item - если это может быть null, вам необходимо исключить эти элементы, поскольку вы используете свойство category.ID:

var model = from i in Items
            where i.Category != null
            join c in Categories on i.Category.ID equals c.ID
            where c.Menu !=null
            join m in Menus on c.Menu.ID equals m.ID
            where m.Name == menuName
            select i;

Изменить в ответ на комментарий:

Поскольку никакие свойства не являются нулевыми, мы можем снова удалить эту часть из запроса, но вам также нужно указать, какие связанные сущности вы хотите реализовать при извлечении сущностей из контекста. В вашем случае вам также необходимо соответствующее свойство Category, которое можно указать с помощью Include():

var model = from i in Items.Include("Category")
            join c in Categories on i.Category.ID equals c.ID
            where c.Menu !=null
            join m in Menus on c.Menu.ID equals m.ID
            where m.Name == menuName
            select i;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...