首页 > 解决方案 > 无法使用实体框架将新数据更新到 MVC 中的表

问题描述

我有一个电影模型:

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

        [Required]
        [StringLength(255)]
        public string Name { get; set; }

        [Required]
        public string Address { get; set; }

        [Required]
        [Range(0, int.MaxValue, ErrorMessage = "Please enter valid number")]
        [Display(Name = "Total Seats")]
        public int TotalSeatsNumber { get; set; }

        public List<Seat>TotalSeats { get; set; }

        public OpeningHour OpeningHour { get; set; }

        [Required]
        [Display(Name = "Opens At")]
        public byte OpeningHourId { get; set; }

        public ClosingHour ClosingHour { get; set; }

        [Required]
        [Display(Name = "Closes At")]
        public byte ClosingHourId { get; set; }

        public Cinema() { }

我有一个 TotalSeatsNumber 属性,因此当管理员填写表格(在网站内)以创建新电影院时,他必须指定电影院应包含多少个座位。

我还创建了一个名为 TotalsSeats 的席位列表,稍后我尝试根据管理员选择的席位数量来初始化席位。你可以在这里看到我正在尝试做的事情:

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Save(Cinema cinema)
        {
            if (!ModelState.IsValid)
            {
                var viewModel = new CinemaFormViewModel(cinema)
                {
                    OpeningHours = _context.OpeningHours.ToList(),
                    ClosingHours = _context.ClosingHours.ToList()
                };
                return View("CinemaForm", viewModel);
            }
            if (cinema.Id == 0)
            {
                cinema.TotalSeats = SetSeats(cinema.TotalSeatsNumber);
                _context.Cinemas.Add(cinema);
            }
            else
            {
                var cinemaInDb = _context.Cinemas.Single(c => c.Id == cinema.Id);

                cinemaInDb.Name = cinema.Name;
                cinemaInDb.Address = cinema.Address;
                cinemaInDb.TotalSeatsNumber = cinema.TotalSeatsNumber;
                cinemaInDb.TotalSeats = cinema.TotalSeats;
                cinemaInDb.OpeningHourId = cinema.OpeningHourId;
                cinemaInDb.ClosingHourId = cinema.ClosingHourId;
            }
            _context.SaveChanges();

            return RedirectToAction("Index", "Cinemas");
        }

SetSeats 函数返回一个席位列表,我在其中初始化了他们的 ID、位置和可用性。以防万一,我将在此处添加我的 Seat Model 和 SetSeats 函数:

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

        [Required]
        public string Location { get; set; }

        [Required]
        public bool isAvailable { get; set; }

        public Seat()
        {
            isAvailable = true;
        }
    }
public List<Seat> SetSeats(int totalSeatsNumber)
        {
            List<Seat> totalSeats = new List<Seat>();
            char rowLetter = 'a';
            int seatNumInRow = 1;
            for (int i = 1; i <= totalSeatsNumber; i++, seatNumInRow++)
            {
                totalSeats.Add(new Seat() { Id = i, Location = rowLetter + ("" + seatNumInRow), isAvailable = true });
                if ((i % 10) == 0)
                {
                    rowLetter++;
                    seatNumInRow = 0;
                }
            }

            return totalSeats;
        }

我尝试这样做的原因是我希望用户在订购某个电影院的电影票时能够选择一个特定的座位。

问题是当我尝试 SaveChanges() 时,它会抛出一个异常:

System.Data.Entity.Infrastructure.DbUpdateException:'保存不为其关系公开外键属性的实体时发生错误。EntityEntries 属性将返回 null,因为无法将单个实体标识为异常源。通过在实体类型中公开外键属性,可以更轻松地在保存时处理异常。有关详细信息,请参阅 InnerException。

调试时,我可以看到我的“电影”实例已正确更新,完全符合我的要求。但是尝试将其保存到数据库时失败。

标签: c#asp.net-mvcentity-frameworkforeign-keys

解决方案


您的 Seat 类与 Cinema 类没有任何关系,但您正在尝试添加 list ,因此添加外键 CinemaId

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

         ......

         public int CinemaId { get; set; }

         public virtual Cinema Cinema {get; set;}
}

更改后您将必须迁移到 db


推荐阅读