更新实体框架数据库结果"由于一个或多个外键属性不可为空,因此无法更改关系"

时间:2016-02-22 14:49:13

标签: c# database entity-framework

我试图更新我的数据库表,但我一直收到外键错误。

  

操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,   必须为foreign-key属性分配另一个非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; }
}

乘客表有预订表的外键。一个&#34;预订&#34;可以有多个乘客,这就是为什么我使用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;
    }

我仍然收到错误。似乎无法弄清楚我做错了什么。我知道外键有问题,实体框架无法对其进行映射。

还有其他建议吗?

1 个答案:

答案 0 :(得分:1)

我认为您的代码存在多个问题:

// 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);

是无用的,因为使用上下文提取了bookingFromDatabase并对其进行了跟踪。

为了通知EF数据上下文你正在更新bookingFromDatabase,你可以这样做:

_db.Entry(bookingFromDatabase).State = EntityState.Modified;

在致电_db.SaveChanges();

之前