我是ASP.NET核心和EF核心的新手。请检查我的代码,让我知道我在做什么错。
** AuthorId违反外键约束。 **无法跟踪BookCategory实体,因为正在跟踪具有相同ID的另一个实例
图书模型
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; }
}
BookCategory模型
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));
}
答案 0 :(得分:1)
您需要在模型内的id属性上添加key属性。
接下来需要更新的是告诉_db,然后先更新您的实体,然后才保存更改。
为什么要使用异步并等待?这些控制器动作会减慢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);
}