阻止EF尝试更新/插入子对象

时间:2016-09-28 13:01:44

标签: entity-framework entity-framework-6

我有一个具有City属性的Address对象。当创建一个全新的地址通过EF6插入时,我填写所有必需的基本地址属性(地址第1行,邮政编码等),但我不需要一个完全水合的城市实例,只要它有ID像这样:

address.City = new City { Id = 1 };

当我尝试插入我的地址时,它也会尝试对City的属性进行验证,但我不想在City上进行任何CRUD,因为我需要的只是它的ID。

我发现下面的问题引入了我从DbContext分离条目,以便EF不会尝试对所述对象进行CRUD:

How do I stop Entity Framework from trying to save/insert child objects?

当我分离City实例时,似乎正在发生的事情是它也将其清空,因此我的地址具有空的City属性。这是一个问题,因为City也是必需的,因此抛出DbEntityValidationException说"城市字段是必需的"。

我是EF的新手,所以也许我开始讨论这一切的方式是错误的。

修改根据请求,这是我的所有代码:

在我的客户端中构建我的地址实体,然后将其传递给WebApi端点:

var user = new AppUser { Id = 1 };
var address = new Address
{
    City = new City { Id = 277 },
    Line1 = "123 whatever ln",
    PostalCode = "01233",
    CreatedBy = user,
    ModifiedBy = user,
    CreatedOn = DateTime.Today,
    ModifiedOn = DateTime.Today
};

在我的ASP.NET应用程序中,我创建了一个我想要从上下文中分离的实例数组:

Detached = new object[] {
    value.Principle.ModifiedBy,
    value.Principle.CreatedBy,
    value.Principle.City
};

在保存之前,我分离了数组中的所有实例:

foreach (var d in DetachedObjects)
{
    dbContext.Entry(d).State = EntityState.Detached;
}
dbContext.SaveChanges();

想到与分离属性一起发生的事情是,它只是告诉EF不要对它们做任何CRUD,但是我不希望它将它们归零,因为我想要父/原则实体拥有其FK的ID。

以下是我的地址和城市课程:

[DebuggerDisplay("{Line1}")]
public class Address : CisEntity
{
    [MaxLength(200)]
    [Required]
    public string Line1 { get; set; }

    [MaxLength(200)]
    public string Line2 { get; set; }

    [Required]
    public City City { get; set; }

    [MaxLength(25)]
    public string PostalCode { get; set; }
}

[DebuggerDisplay("{Name}, {Province.Name}, {Province.Country.Name}")]
public class City : CisEntity, IEntityName
{
    [Required]
    public Province Province { get; set; }

    [MaxLength(100)]
    public string Name { get; set; }
}

2 个答案:

答案 0 :(得分:0)

如果您在执行CRUD时不想要城市,请删除所需的属性。如果你真的需要一个城市作为你的地址在你的程序中,而不是在数据库中,那么就像你一样,在执行地址上的CRUD之前将城市作品归零。否则将插入。您应该查看数据库中表格的外观。 EF将在单独的表中跟踪这些,并且Address上的City列将是外键。如果使用required属性在Address上装饰City属性,则表示该列不可为空。这意味着在数据库中,此列必须包含City表中记录的外键,因此City必须存在。

答案 1 :(得分:0)

我相信我理解您的问题,三年后我会回答。大声笑。

对于主要实体, context.Addresses.Add(address);

对于相关实体或子实体, context.Entry(address.City).State = EntityState.Modified;

对其他所有相关实体执行此操作。