Вариант музыкального магазина MVC - ошибка «Последовательность не содержит элементов» - PullRequest
1 голос
/ 03 января 2012

Я хотел создать свой собственный базовый онлайн-магазин, поэтому я осмотрелся и в итоге решил изменить учебник MVC Music Store, чтобы он соответствовал моим потребностям.

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

Это происходит только в разделе StoreController \ Browse. Когда я пытаюсь просмотреть все элементы в определенной категории, я получаю System.InvalidOperationException «Последовательность не содержит элементов»

Код, используемый в контроллере:

public ActionResult Browse(string cat)
{
var categoryModel = storeDB.Categories.Include("Products")
    .Single(g => g.CatName == cat);

return View(categoryModel);
}

И вид выглядит так:

@model TPATK_shop.Models.Category

@{
    ViewBag.Title = "Browse";
}

<h2>Browsing Category: @Model.CatName</h2>

<ul>
    @foreach (var product in Model.Products)
    {
        <li>
            @product.ProdName
        </li>
    }
</ul>

У меня все мои классы и сущности настроены следующим образом:

namespace TPATK_shop.Models
{
    public partial class Category
    {
        public int CategoryId { get; set; }
        public string CatName { get; set; }
        public string Description { get; set; }

        public List<Product> Products { get; set; }
    }
}

namespace TPATK_shop.Models
{
    public class Product
    {
        public int ProductId { get; set; }
        public int CategoryId { get; set; }
        public string ProdName { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        public string ImageURL { get; set; }

        public Category Category { get; set; }
    }
}

namespace TPATK_shop.Models
{
    public class TPATKStoreEntities : DbContext
    {
        public DbSet<Product> Products { get; set; }
        public DbSet<Category> Categories { get; set; }
    }
}

Я исследовал проблему и, похоже, не могу найти решение. Я пробовал singleordefault, но все равно получаю ошибку.

Я подтвердил, что все данные присутствуют в БД, а ключи верны.

Когда запускается мой проект, запись в global.asax запускает следующий код для заполнения БД (в целях тестирования - как подробно описано в пошаговом руководстве)

namespace TPATK_shop.Models
{
    public class SampleData :  DropCreateDatabaseAlways<TPATKStoreEntities>
    //public class SampleData : DropCreateDatabaseIfModelChanges<TPATKStoreEntities>
    {
        protected override void Seed(TPATKStoreEntities context)
        {
            var categories = new List<Category>
            {
                new Category { CatName = "50's" , Description = "50's stuff" },
                new Category { CatName = "Weddings" , Description = "Wedding stuff" },
                new Category { CatName = "Dribble Bibs" , Description = "Dribble bibs for kids" },
                new Category { CatName = "Xmas" , Description = "Xmas stuff" },
            };

            new List<Product>
            {
                new Product { ProdName = "Headband 1", Description = "Des for headband 1", Category = categories.Single(g => g.CatName == "50's"), Price = 8.99M, ImageURL = "/Content/Images/placeholder.gif" },
                new Product { ProdName = "Headband 2", Description = "Des for headband 2", Category = categories.Single(g => g.CatName == "Weddings"), Price = 8.99M, ImageURL = "/Content/Images/placeholder.gif" },
                new Product { ProdName = "Headband 3", Description = "Des for headband 3", Category = categories.Single(g => g.CatName == "Dribble Bibs"), Price = 8.99M, ImageURL = "/Content/Images/placeholder.gif" },
                new Product { ProdName = "Headband 4", Description = "Des for headband 4", Category = categories.Single(g => g.CatName == "Xmas"), Price = 8.99M, ImageURL = "/Content/Images/placeholder.gif" },
                new Product { ProdName = "Headband 4", Description = "Des for headband 5", Category = categories.Single(g => g.CatName == "Xmas"), Price = 8.99M, ImageURL = "/Content/Images/placeholder.gif" },
            }.ForEach(a => context.Products.Add(a));
        }
    }
}

Кто-нибудь может понять, почему я получаю ошибку? Любая помощь будет в значительной степени получена.

Ответы [ 3 ]

3 голосов
/ 03 января 2012

Это связано с тем, что в поставляемом cat нет соответствующей записи в базе данных. Используйте метод SingleOrDefault для извлечения объекта, он вернет null, если не было записи.

public ActionResult Browse(string cat)
{
    var categoryModel = storeDB.Catagories.Include("Products")
        .SingleOrDefault(g => g.CatName == cat);

    if (categoryModel == null)
       return RedirectToAction("Index");

    return View(categoryModel);
}

Возможно, в этом случае MVC не может связать значение с параметром cat и для него установлено значение null. Поэтому проверьте, передаете ли вы аргумент строки запроса с именем cat.

1 голос
/ 03 января 2012

Есть орфографическая ошибка, которая вызывает ошибку.Вместо «Категория» вы использовали «Catagory».Теперь, когда вы использовали POCO Code-first, существует соглашение, согласно которому имя модели множится для соответствия таблице базы данных.Поскольку не существует такого слова, как «CATAGORY», плюризация не выполняется.

Чтобы исправить эту ошибку, либо переименуйте Catagory в Category везде, либо измените Catagories на Categories в классе DbContext.

или

вы можете украсить свой класс Catagory следующим образом

[Table("Catagories"]
public class Catagory

, если вы следуете этому подходу, измените написание в Product Model с CategoryId на CatagoryId

0 голосов
/ 03 января 2012

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

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

Также может возникнуть проблема, поскольку система EF Code First пытается сопоставить ключи на основе имен свойств. У вас есть Продукт, ссылающийся на объект Catagory , но используется идентификатор CategoryID (с и "e", а не "a").

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...