我有一个具有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; }
}
答案 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;
对其他所有相关实体执行此操作。