Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用具有一对多关系的实体列表属性更新数据库上的实体_C#_Entity Framework_Asp.net Mvc 4_One To Many - Fatal编程技术网

C# 使用具有一对多关系的实体列表属性更新数据库上的实体

C# 使用具有一对多关系的实体列表属性更新数据库上的实体,c#,entity-framework,asp.net-mvc-4,one-to-many,C#,Entity Framework,Asp.net Mvc 4,One To Many,为了更好地理解,我将创建一些更简单的实体: 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 {

为了更好地理解,我将创建一些更简单的实体:

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; }
}
公共教室
{
[必需]
公共int Id{get;set;}
[必需]
公共int名称{get;set;}
[必需]
[栏目(“房屋Id”)]
public int HouseId{get;set;}
公共虚拟房屋{get;set;}
}
公屋
{
[必需]
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection房间{get;set;}
}
现在,假设我有一个房屋实体,在数据库中有4个与之相关的房间。我想更新房子并移除其中的两个房间。我正在使用Asp.NETMVC4顺便说一句

        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;
var house=HouseRepository.Get(id);
house.Name=model.Name;//一些绳子
house.Name=model.Rooms;//ICollection from view中有两个房间,因为用户删除了视图中的另外两个房间
HouseRepository.SaveChanges();
归还房屋;
发生的情况是,我得到的错误是:操作失败:关系无法更改,因为一个或多个外键属性不可为null。对关系进行更改时,相关外键属性设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象

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


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

删除您不再希望单独删除的房间,以便从模型中明确删除它们-类似于此:

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
}

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

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

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

通过此配置,EF知道,当您从
房间
集合中删除房间对象时,也可以安全地为DB删除房间。

假设您的设置为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();

创建复合键以便能够从父项中删除子项太多了。然后,EF仍然不会删除房间,因为它会尝试将FK值置零,或者,如果FK值不可置零,则将其替换为新值。您的语句不正确。如果使用标识关系,即与组合键的关系,其中外键是主键的一部分,则自动删除将起作用。如果您从父集合中删除一个房间,EF知道,如果没有父集合,该房间将无法存在,并且它将从DB中删除该房间。好的,您可能是对的。不过,我不会创建一个复合键来适应ORM实现。复合键是笨拙的东西。