[英]Error while trying to cascade-delete
尝试从数据库中删除项目时,出现以下错误消息:
操作失败:由于一个或多个外键属性不可为空,因此无法更改该关系。 对关系进行更改时,相关的外键属性将设置为空值。 如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。
我已经阅读了许多有关此问题的主题,但是似乎没有一个对您有帮助的(或者也许我不太了解它们)。
我的模型是:
public class ARDOperation
{
[Key]
public int ARD { get; set; }
[Required]
public virtual ICollection<Act> Actions { get; set; }
public ARDOperation()
{
this.Actions = new List<Act>();
}
}
public class Act
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ARDID { get; set; }
public int ARDOperationId { get; set; }
[ForeignKey("ARDOperationId")]
public virtual ARDOperation ARDOperation { get; set; }
public string Data { get; set; }
[EnumDataType(typeof(ARDState))]
public ARDState State { get; set; }
}
我还定义了一个流畅的API:
public class ARDOperationDBContext : DbContext
{
public DbSet<ARDOperation> ARDOperation { get; set; }
//public DbSet<Act> Act { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Act>()
.HasRequired(t => t.ARDOperation)
.WithMany(t => t.Actions)
.HasForeignKey(d => d.ARDOperationId)
.WillCascadeOnDelete(true);
//modelBuilder.Entity<ARDOperation>()
}
控制器中的方法:
internal void RemoveAction(int ARDID)
{
var op = ARDOperationDB.ARDOperation.Find(ARDID);
if (op != null)
{
//will not remove the "idle" action
if (op.Actions.Count > 1)
{
Act act = op.Actions.ElementAt(1);
op.Actions.Remove(act);
//ARDOperationDB.Entry(op).State = EntityState.Modified;
ARDOperationDB.SaveChanges();
}
}
}
我尝试使用代码优先方法将“ ARDOperationId”属性定义为可为空(int?),并且我没有通过这种方式得到任何错误,但是子级的数据仍然保留在DB中。
我认为我缺少与访问该法案模型有关的内容。
谢谢您的帮助,尤瓦尔。
看看EF专家关于remove方法的[this answer] [1]。
EntityCollection.Remove(childEntity)将parent和childEntity之间的关系标记为Deleted。 如果将childEntity本身从数据库中删除,则调用SaveChanges时究竟发生了什么,取决于两者之间的关系类型:
如果该关系是可选的,即从数据库中的子项到父项引用的外键允许使用NULL值,则该外键将设置为null,并且如果您调用SaveChanges,则childEntity的此NULL值将被写入数据库(也就是说,两者之间的关系已删除)。 使用SQL UPDATE语句会发生这种情况。 没有发生DELETE语句。
如果需要该关系(FK不允许使用NULL值)并且该关系没有标识(这意味着外键不属于子级(复合)主键的一部分),则必须将子级添加到另一个父级中否则您必须显式删除该子项(然后使用DeleteObject)。 如果您不执行任何这些操作,则将违反引用约束,并且在调用SaveChanges时EF将引发异常-臭名昭著的“由于一个或多个外键属性是不可空的,因此无法更改关系”异常或类似。
如果该关系是可识别的(那么这是必需的,因为主键的任何部分不能为NULL),EF也会将childEntity标记为Deleted。 如果调用SaveChanges,则会将SQL DELETE语句发送到数据库。 如果没有违反数据库中的其他引用约束,则将删除该实体,否则将引发异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.