我有一个模型,我在使用实体框架4.1管理关系时遇到了麻烦。
这里的模型(简化):
public class UserConfig {
[Key]
[Column("id", TypeName = "bigint")]
public long Id { get; set;}
[InverseProperty("UserConfigId")]
public virtual List<ColumnConfig> ColumnConfigs { get; set; }
}
public class ColumnConfig {
[Key]
[Column("id", TypeName = "bigint")]
public long Id { get; set; }
[Column("user_config_id", TypeName = "bigint")]
public long UserConfigId { get; set; }
[Column("width", TypeName = "int")]
public int Width{ get; set; }
[Column("col_name", TypeName = "varchar")]
public string ColumnName{ get; set; }
}
模型表示用户和UI中数据表的自定义视图。他们按照自己的方式调整列大小,然后保存设置。我有一个web服务,接受他们想要的列列表及其各自的宽度。
我遇到的问题是在我的网络服务中更新用户的ColumnConfigs。 webservice没有收到ColumnConfig id,所以我的方法是尝试先删除用户的所有现有ColumnConfigs,然后根据传入的新值创建一组新的对象。
我无法删除任何ColumnConfig对象。这是我的代码:
public void UpdateUserConfig(UserConfig uc) {
UserConfig origUserConf = ctx.ColumnConfigs.Find(new object[] {uc.Id});
origUserConf.ForEach(uc => ctx.ColumnConfigs.Remove(uc)); // remove old
origUserConf.ColumnConfigs = uc.ColumnConfigs; // add new
ctx.SaveChanges();
}
这不起作用,它给出错误:
System.InvalidOperationException: The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
我不确定为什么认为这里有一个空约束。我没有指定任何字段是必需的。
答案 0 :(得分:0)
删除子关系的最简单方法是调用:
origUserConfig.ColumnConfigs.Clear();
不幸的是,这对你不起作用有两个原因:(1)你的父和子实体之间定义了一个不可为空的关系,(2)即使关系被定义为可空,它也会孤立的孩子而不是删除它。
阅读本文(Deleting Foreign Key Relationships in EF4)以了解EF如何处理删除子实体。在你的情况下,你属于1号案件。
就你所犯的错误而言,改变你的foreach以使用List<T>
类之外的ForEach方法:
origUserConf.ColumnConfigs.ForEach(col => ctx.ColumnConfigs.Remove(col))