2

我将组成一些更简单的实体以更好地理解:

public class Room
{
    [Required]
    public int Id { get; set; }

    [Required]
    public int Name { get; set; }

    [Required]
    [Column("House_Id")]
    public int HouseId { get; set; }
    public virtual House House { get; set; }
}


public class House
{
    [Required]
    public int Id{ get; set; }

    public string Name { get; set; }

    public virtual ICollection<Room> Rooms { get; set; }
}

现在,可以说,我有一个 House 实体,在数据库中有 4 个与之相关的房间。我想更新房子并删除其中的 2 个房间。我正在使用 Asp.Net MVC4 顺便说一句。

        var house = HouseRepository.Get(id);
        house.Name = model.Name; // Some string
        house.Name = model.Rooms; // ICollection<Room> from view with 2 rooms in it, cuz user deleted other two in view
        HouseRepository.SaveChanges();
        return house;

发生的情况是我收到错误消息:操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

我需要找到一个解决方案如何从数据库中删除不相关的房间。我应该在何时何地做?我已经尝试过一些东西,但现在即使我正在添加房间,我也会遇到这个错误。

有什么简单的方法告诉EF它应该自己删除这些房间吗?

4

3 回答 3

1

只有使用标识关系,EF 才能自动删除孤儿。您需要为Room对象定义一个复合键,它由Id和组成HouseID

modelbuilder.Entity<Room>()
            .HasKey(o => new { o.ID, o.HouseId });

modelbuilder.Entity<Room>()
            .Property(o => o.ID)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

使用此配置,EF 知道,当您从Rooms集合中删除房间对象时,也可以安全地删除数据库的房间。

于 2013-10-22T08:57:56.813 回答
0

删除您不再希望单独从模型中显式删除它们的房间 - 相当于这个:

foreach(Room room in house.Rooms.ToList())
{
    if(model.Rooms.FirstOrDefault(x=>x.Id == room.Id) == null)
         dbContext.Rooms.Remove(room); //assumes the room is attached to your context, you may need to do a get
}
于 2013-10-22T08:33:23.750 回答
0

假设您设置的 1 个房子当前有 4 个房间与之关联,这应该可以:

var db = new TestContext();
var house = db.Houses.Include("Rooms").First();

// Grab rooms 2 & 3 for removal
var roomsToRemove = house.Rooms.OrderBy(r => r.Id).Skip(1).Take(2).ToList();
roomsToRemove.ForEach(r => db.Rooms.Remove(r));

db.SaveChanges();
于 2016-06-23T18:48:14.103 回答