我正在尝试更新数据库表,但不断收到外键错误。
操作失败:无法更改关系,因为一个或多个外键属性不可为空。对关系进行更改时,相关的外键属性将设置为 null 值。如果外键不支持空值,则必须定义一个新关系, 必须为外键属性分配另一个非 null 值,否则必须删除不相关的对象。
我有两个表,其中包含使用上下文类和ContextInitializer
类自动填充的数据。
表 1:( Bookings
) 是使用此模型创建的:
public class Booking
{
public int Id { get; set; }
public string BookingNumber { get; set; }
public DateTime OutboundDate { get; set; }
public DateTime ReturnDate { get; set; }
public string Route { get; set; }
public string ReturnRoute { get; set; }
public string Passengers { get; set; }
public string Pet { get; set; }
public string VehicleType { get; set; }
// Passengers
public virtual ICollection<Passenger> PassengersList { get; set; }
}
表 2 ( Passenger
) 是使用此模型创建的:
public enum PassengerType
{
Adult, Children, Infant
}
public enum Title
{
Mr, Mrs
}
public class Passenger
{
public int Id { get; set; }
public int BookingId { get; set; }
public Title? Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public PassengerType? PassengerType { get; set; }
}
乘客表具有预订表的外键。一个"预订"可以有多个乘客,这就是我使用ICollection
列表的原因。
更新
已将我的方法编辑为如下所示:
public bool Execute(Booking booking)
{
// Get booking from database
var bookingFromDatabase = _db.Bookings.Find(booking.Id);
if (bookingFromDatabase != null)
{
// Map passengersList
bookingFromDatabase.PassengersList.Clear();
foreach (var passenger in booking.PassengersList)
{
bookingFromDatabase.PassengersList.Add(passenger);
}
// Save changes in database
_db.Entry(bookingFromDatabase).State = EntityState.Modified;
_db.SaveChanges();
return true;
}
return false;
}
我仍然收到错误。似乎无法弄清楚我做错了什么。我知道外键有问题,实体框架无法快速映射它们。
还有其他建议吗?
我认为您的代码存在多个问题:
// Map passengersList
bookingFromDatabase.PassengersList = booking.PassengersList;
在这里,您正在更改引用本身,它将不再被跟踪。一种方法(当列表很长时效率不高)是清除现有列表并从新列表(未测试)中添加元素:
bookingFromDatabase.PassengersList.Clear();
foreach (var passenger in booking.PassengersList)
bookingFromDatabase.PassengersList.Add(passenger);
附加自
// Save changes in database
_db.Bookings.Attach(bookingFromDatabase);
是无用的,因为bookingFrom数据库是使用上下文获取并被跟踪的。
为了通知 EF 数据上下文您正在更新 bookingFromDatabase,您可以执行以下操作:
_db.Entry(bookingFromDatabase).State = EntityState.Modified;
在呼叫_db.SaveChanges()
之前;