EF Core: обновление идентификатора зависимой сущности «один-ко-многим» - PullRequest
0 голосов
/ 29 июня 2019

Я новичок в ядре ASP.NET и ядре EF. Пожалуйста, проверьте мой код и дайте мне знать, что я делаю неправильно.

** Нарушение ограничения внешнего ключа для AuthorId. ** Сущность BookCategory не может быть отслежена, поскольку отслеживается другой экземпляр с таким же идентификатором

Книжная модель

public class Book
    {
        public int BookId { get; set; }
        public string Title { get; set; }
        public double Price { get; set; }
        public int? Discount { get; set; }
        public string ImagePath { get; set; }
        public int? Stock { get; set; }

        public Author Author { get; set; }
        public int AuthorId { get; set; }

        public BookCategory Category { get; set; }
        public int? CategoryId { get; set; }

        public ICollection<JoinBookTag> BookTags { get; set; }
    }

Модель книжной категории

public class BookCategory
    {
        public int Id { get; set; }

        [Display(Name = "Category Name")]
        public string CategoryName { get; set; }

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

    }

Автор Модель

public class Author
    {
        public int AuthorId { get; set; }
        public string Name { get; set; }

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

BookController

        private readonly ApplicationDbContext _db;
        private readonly HostingEnvironment _hostingEnvironment;


        [BindProperty]
        public BookViewModel ViewModel { get; set; }
        public BookController(ApplicationDbContext db, HostingEnvironment host)
        {
            _db = db;
            _hostingEnvironment = host;
            ViewModel = new BookViewModel()
            {
                Book = new Models.Book(),
                Authors = _db.Authors.ToList(),
                BookCategories = _db.BookCategories.ToList(),
                Tags = _db.Tags.ToList()
            };
        }

...............

[HttpGet]
        public IActionResult Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }
            var book = _db.Books.Include(b => b.Category)
                        .Include(b => b.Author)
                        .SingleOrDefault(b => b.BookId == id);
            if (book == null)
            {
                return NotFound();
            }
            ViewModel.Book = book;
            return View(ViewModel);
        }

[HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(BookViewModel model, int? id)
        {
            if (id == null)
            {
                return NotFound();
            }
            if (id != model.Book.BookId)
            {
                return NotFound();
            }
            if (!ModelState.IsValid)
            {
                /*ViewModel.Book = model.Book;
                return View(ViewModel);*/
                var errors = ModelState.Select(x => x.Value.Errors)
                           .Where(y => y.Count > 0)
                           .ToList();
                return Json(new { errors });
            }
            var dbModel = _db.Books.Include(b => b.Category).Where(b => b.BookId == id).FirstOrDefault();

            var file = HttpContext.Request.Form.Files;
            if (file.Count > 0)
            {
                var RootDirectory = _hostingEnvironment.WebRootPath;
                var extension = Path.GetExtension(file[0].FileName);
                var filePath = Path.Combine(DataContext.ImageDirectory, model.Book.BookId + extension);
                using (var fileStream = new FileStream(Path.Combine(RootDirectory, filePath), FileMode.Create))
                {
                    file[0].CopyTo(fileStream);
                }

                dbModel.ImagePath = @"/" + filePath;
            }
            dbModel.AuthorId = model.Book.AuthorId;
            dbModel.CategoryId = model.Book.CategoryId;
            dbModel.Discount = model.Book.Discount;
            dbModel.Price = model.Book.Price;
            dbModel.Stock = model.Book.Stock;
            dbModel.Title = model.Book.Title;

            await _db.SaveChangesAsync();
            return RedirectToAction(nameof(Index));

        }

1 Ответ

1 голос
/ 29 июня 2019

Вам необходимо добавить ключевой атрибут в свойствах вашего идентификатора внутри ваших моделей.

Следующее, что вам нужно обновить, это сказать _db, чтобы сначала обновлять вашу сущность, а затем только затем сохранять изменения.

Почему вы используете async и await? Эти действия контроллера замедляют UI?

Также вы можете опубликовать модель просмотра книги?

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

    [HttpGet]
    public IActionResult Edit(int? id)
    { 
       //Give this a name other than view model for example BookViewModel
       ViewModel model = new ViewModel();

        if (id == null)
        {
            return NotFound();
        }

        var book = _db.Books.Include(b => b.Category)
                    .Include(b => b.Author)
                    .SingleOrDefault(b => b.BookId == id);

        if (book == null)
        {
            return NotFound();
        }

        model.Book = book;

        return View(model);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(BookViewModel model, int? id)
    {
        if (id == null || id != model.Book.BookId)
        {
            return NotFound();
        }

        if (ModelState.IsValid)
        {
            var dbModel = _db.Books.Include(b => b.Category).Where(b => b.BookId == id).FirstOrDefault();

        var files = HttpContext.Request.Form.Files;
        if (files.Any())
        {
            var RootDirectory = _hostingEnvironment.WebRootPath;
            var extension = Path.GetExtension(files[0].FileName);
            var filePath = Path.Combine(DataContext.ImageDirectory, model.Book.BookId + extension);
            using (var fileStream = new FileStream(Path.Combine(RootDirectory, filePath), FileMode.Create))
            {
                file[0].CopyTo(fileStream);
            }

            dbModel.ImagePath = @"/" + filePath;
        }

        dbModel.AuthorId = model.Book.AuthorId;
        dbModel.CategoryId = model.Book.CategoryId;
        dbModel.Discount = model.Book.Discount;
        dbModel.Price = model.Book.Price;
        dbModel.Stock = model.Book.Stock;
        dbModel.Title = model.Book.Title;

        await _db.Books.UpdateAsync(dbModel);
        await _db.SaveChangesAsync();

        return RedirectToAction(nameof(Index));

        }

        return View(model);

    }
...