简体   繁体   English

使用一对多关系实体列表的属性更新db上的实体

[英]Update entity on db with a property of list of entities with one-to-many relationship

I will make up some simpler entities to get a better understanding: 我将组成一些更简单的实体以获得更好的理解:

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; }
}

Now, lets say, that i have one House entity with 4 rooms related to it in database. 现在,可以说,我在数据库中有一个与4个房间相关的众议院实体。 I want to update the House and remove 2 of its rooms. 我要更新房屋并删除其2个房间。 I'm using Asp.Net MVC4 btw. 我正在使用Asp.Net MVC4 btw。

        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;

What happens, is that i get error saying : The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. 发生的是,我得到一条错误消息:操作失败:由于一个或多个外键属性不可为空,因此无法更改关系。 When a change is made to a relationship, the related foreign-key property is set to a null value. 对关系进行更改时,相关的外键属性将设置为空值。 If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted. 如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

I need to find a solution how to delete the unrelated Rooms from db. 我需要找到一个解决方案,如何从数据库中删除不相关的房间。 When and where i should do it? 我应该在何时何地进行操作? I've tried something already, but now i get that error even I'm adding rooms. 我已经尝试过一些东西,但是现在即使添加房间,也会出现该错误。

Is there any simple way to tell EF that it should delete these rooms by itself? 是否有任何简单的方法告诉EF它应自行删除这些房间?

EF can delete orphans automatically only if you use the identifying relationship. EF仅在您使用识别关系的情况下才能自动删除孤儿。 You need to define a composite key for the Room object, that consists of Id and HouseID . 您需要为Room对象定义一个组合键,该组合键由IdHouseID

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

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

With this configuration EF knows, that when you remove a room object from the Rooms collection, it's safe to remove the room for the DB as well. 通过这种配置,EF知道,当您从“ Rooms集合中删除房间对象时,也可以安全地为数据库删除房间。

Delete the Rooms you no longer want individually to explicitly remove them from the model - something equivalent to this: 删除不再需要的房间,以从模型中显式删除它们-等效于以下操作:

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
}

Assuming your setup of 1 house that has 4 rooms currently associated to it, this should work: 假设您设置的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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM