【发布时间】:2019-07-19 03:40:26
【问题描述】:
我正在尝试纠正以下关系。出于某种原因,在 ChildClass 上设置的主键使用了 ParentClassId 和 ChildClassId 的组合,而它本应使用 ChildClassId。
public partial class ParentClass
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ParentClassId { get; set; }
public DateTime SomeDate { get; set; }
public string SomeString { get; set; }
public virtual ICollection<ChildClass> ChildClasses { get; set; }
}
public partial class ChildClass
{
[Key, ForeignKey("ParentClass"), Column(Order = 1)]
public int ParentClassId { get; set; }
[Key, Column(Order = 2)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ChildClassId { get; set; }
public virtual ParentClass ParentClass { get; set; }
public DateTime SomeDate { get; set; }
public string SomeString { get; set; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ParentClass>()
.HasMany(e => e.ChildClasses)
.WithRequired(e => e.ParentClass);
}
到目前为止,我有:
public partial class ParentClass
{
public int ParentClassId { get; set; }
public DateTime SomeDate { get; set; }
public string SomeString { get; set; }
public virtual ICollection<ChildClass> ChildClasses { get; set; }
}
public partial class ChildClass
{
public int ChildClassId { get; set; }
public int ParentClassId { get; set; }
public virtual ParentClass ParentClass { get; set; }
public DateTime SomeDate { get; set; }
public string SomeString { get; set; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ParentClass>()
.HasMany(e => e.ChildClasses)
.WithRequired(e => e.ParentClass);
}
这提供了一个迁移脚本,它只是按预期删除并重新创建主键。
现在,当我加载父对象时,清除子对象并重新创建它们,然后尝试保存更改
ParentClass p = await db.ParentClasses.Include("ChildClasses").SingleOrDefaultAsync(r => r.ParentClassId == 1).ConfigureAwait(false);
p.ChildClasses.Clear();
ChildClass c = new ChildClass { SomeDate = DateTime.Now, SomeString="some string" };
p.ChildClasses.Add(c);
await db.SaveChangesAsync().ConfigureAwait(false); //<< Error on this
我得到错误:
操作失败:无法更改关系,因为 一个或多个外键属性不可为空。当一个 对关系进行更改,相关的外键属性是 设置为空值。如果外键不支持空值, 必须定义一个新的关系,外键属性必须是 分配了另一个非空值,或者不相关的对象必须是 已删除。
表和关联的键、索引等看起来不错。 SaveChanges 行没有到达数据库,因此模型中的某处(我看不到)似乎不尊重更新的关系。
编辑:基于阅读,我也尝试过如下迭代并得到相同的错误。
foreach (ChildClass t in p.ChildClasses.ToList()) p.ChildClasses.Remove(t);
我错过了什么?
【问题讨论】:
-
你在做 p.ChildClasses.Clear(); 时想要什么?
-
p.ChildClasses.Clear() 真的会删除子类吗?您收到的错误听起来像是现在才尝试在没有 ParentId 的情况下保存子类。
-
只是为了澄清,p.ChildClasses.Clear();是在我更改关系之前一直有效的现有代码。
-
@mattpm,我认为,Remove() 也与 Clear() 一样。尝试使用上下文删除它。像 db.Remove(t)
-
@DIlshod - 干杯。我使用的 EF 版本似乎没有 db.Remove(t) 方法。但是,根据您的建议,我尝试使用 db.ChildClasses.RemoveRange(p.ChildClasses.ToList());相反,这已经删除了子对象。将在星期一再次接收。
标签: c# asp.net-mvc entity-framework-6