使用 Entity Framework 在 MVC 中将新数据更新到 table 时遇到问题
Having trouble to update new data to a table in MVC using Entity Framework
我有一个电影模型:
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 函数 returns 我在其中初始化其 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: 'An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.'
调试时,我可以看到我的“影院”实例已正确更新,完全符合我的要求。但是在尝试将其保存到数据库时失败了。
你的座位class与Cinemaclass没有任何关系,但你想添加一个列表,所以添加一个外键CinemaId
public class Seat
{
public int Id { get; set; }
......
public int CinemaId { get; set; }
public virtual Cinema Cinema {get; set;}
}
更改后必须迁移到数据库
您必须先迁移以确保数据库模式与 C# 中的 Db 模型异步。
我有一个电影模型:
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 函数 returns 我在其中初始化其 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: 'An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.'
调试时,我可以看到我的“影院”实例已正确更新,完全符合我的要求。但是在尝试将其保存到数据库时失败了。
你的座位class与Cinemaclass没有任何关系,但你想添加一个列表,所以添加一个外键CinemaId
public class Seat
{
public int Id { get; set; }
......
public int CinemaId { get; set; }
public virtual Cinema Cinema {get; set;}
}
更改后必须迁移到数据库
您必须先迁移以确保数据库模式与 C# 中的 Db 模型异步。