更新实体框架数据库会导致“无法更改关系,因为一个或多个外键属性不可为空”

本文关键字:一个 属性 因为 数据库 实体 框架 关系 更新 | 更新日期: 2023-09-27 18:35:38

我正在尝试更新数据库表,但不断收到外键错误。

操作失败:无法更改关系,因为一个或多个外键属性不可为空。对关系进行更改时,相关的外键属性将设置为 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; }
}

表 2Passenger ) 是使用此模型创建的:

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()之前;