AminMhmdi Ответов: 1

Как вставить значение в свойство навигации в entity framework


у меня есть ниже модель:

public class Book
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int BookID { get; set; }

        public string bookName { get; set; }
        public string bookAuthor { get; set; }

        public string bookTranslator { get; set; }
      
        public DateTime registerDate { get; set; }

        
       public virtual ICollection<Category> Category { get; set; }
    }

 public class Category
    {

        public int CategoryId { get; set; }

        [StringLength(50)]
        public string categoryName { get; set; }

        [DataType(DataType.Text)]
        public string categoryDescription { get; set; }

        public virtual ICollection<Book> Books { get; set; }
    }


теперь я хочу добавить категорию в свою книгу
в контроллерах:
 int catID = int.Parse(form["ddlCat"]);
 IEnumerable<Category> _cats = db.Categories.Where(x => x.CategoryId == catID);
 book.Category.Add(_cats.FirstOrDefault());
 db.Books.Add(book);
db.SaveChanges();


и в поле зрения:

<div class="form-group">
     <label class="control-label col-md-2" for="DepartmentID">Cats</label>
     <div class="col-md-10">
        @Html.DropDownList("ddlCat",new SelectList(ViewBag.Category,"Value","Text"))
                @Html.ValidationMessageFor(model => model.Category)
            </div>
        </div>


Что я уже пробовал:

я пытаюсь добавить выбранную пользователем категорию, но это дает мне ошибку в следующей строке

book.Category.Add(_cats.FirstOrDefault());


Ссылка на объект не установлена на экземпляр объекта.

1 Ответов

Рейтинг:
5

Dave Kreskowiak

Отладчик мог бы дать вам намек на то, что происходит. Чтобы получить категорию, вы должны запустить FirstOrDefault на IQueryable вместо этого. То, что сделал ваш код, - это немедленно обработал возврат запроса как IEnumerable. Если запрос не вернул ни одной строки, то IEnumerable будет равен null. Поскольку вы не можете вызвать метод или свойство на null, вы получаете сообщение об исключении, которое вы получили.

// Get the Category Id from the form
int catID = int.Parse(form["ddlCat"]);

// Get the Category object from the database
var category = db.Categories.Where(x => x.CategoryId == catID).FirstOrDefault();

// Did we get back a Category object?
if (category != null)
{
    // Add the Category to the Book Categories collection
    book.Category.Add(category);
}

// Add the Book to the Books table in the database
db.Books.Add(book);
db.SaveChanges();


AminMhmdi

а чем отличается мой код от вашего?

Dave Kreskowiak

Я уже говорил тебе. Вы рассматриваете запрос как IEnumerable, а не IQueryable. Предложение Where возвращает IQueryable. Но ваш код сужает его до IEnumerable, потому что IQueryable наследуется от IEnumerable. Ваш способ написания его использует небольшую причуду IQueryable под названием "отложенное выполнение". Запрос не выполняется до тех пор, пока вы не доберетесь до _cat.FirstOrDefault(). Ну, на данный момент Вы уже преобразовали IQueryable в IEnumerable. Значение _cat теперь равно null, и вы не можете вызвать FirstOrDefault для нулевого объекта.