添加新的子实体并一次性更新父实体

Add new child entity and update parent entity in one turn

我有tableentry和一个tabletypeentry 有一个 type 类型可以在许多条目中(n 对 1 关系)。该类型显示在 editable ComboBox 中。如果用户输入的类型尚不存在,则应创建该类型,并且相关 entrytype 应更新为新的类型实体。

我如何加载条目(急切加载):

var entries = dbContext.entry.Include(entry => entry.type).ToList();

我如何将类型绑定到组合框:

<Combobox IsEditable="True"
    ItemsSource="{Binding AllTypes, Source={StaticResource typeTableController}}"
    SelectedValue="{Binding Path="Entry.type"}" />

typeTableController 具有数据库中所有现有类型的 属性 (AllTypes)。 Entry 是当前选择的 entry。用户现在可以编辑 ComboBox 文本。如果他按下 "Save" 按钮,则应将此类型添加到数据库(如果尚不存在),或者应将其选中(如果存在)。并且应该保存更新的条目。如果我不必自己处理每个 属性 就好了,因为 type 不是我唯一拥有的

我的第一个方法:

dbContext.Set(entry.getType()).Attach(entry);
dbContext.SaveChanges();

-> InvalidOperationException:参照完整性约束违反

dbContext.Entry(formEntry.type).State = EntityState.Added;
dbContext.Set(entry.getType()).Add(entry);
dbContext.SaveChanges();

-> 将新的 type 添加到类型 table 但同时复制了 type/entry table 中的所有类型和条目(这对我来说真的很奇怪)并且只将现有的两个 entries 之一的类型更新为新的 type。所以如果之前有10种,现在有21种了。

编辑:我的条目:

public partial class entry 
{
    ...
    public Nullable<int> type_id { get; set; }
    ...
    public virtual type type { get; set; }
}

重要: 我尝试时总是崩溃

dbContext.Entry(entry).State = EntityState.Modified;

原因是,我的调试器监视列表中有 entry。似乎这会导致一些冲突。删除它可以解决该问题。

判断类型是已有的还是用户新添加的。检查 type.Id == 0 新类型实体。

if (typeFromCombobox.Id == 0){
    //new type added
    dbContext.Set<type>().Add(typeFromCombobox)
}
entity.type = typeFromCombobox // EF should handle this if you didn't call 'Detach' before
dbContext.SaveChanges()

编辑:不确定:您正在使用组合框绑定,当用户 select 时它应该自动更改 entity.type。所以行 entity.type = typeFromCombobox 是 rebundant

编辑 2:我创建了 sample code

工作正常,entity.typeidentity.type.idSaveChanges 调用

后更新

但是如果我取消注释 this.Configuration.AutoDetectChangesEnabled = false; entity.typeid 将不会更新,直到我手动调用 context.ChangeTracker.DetectChanges();

编辑 3:如果您在加载和保存之间更改了 dbContext,您应该将实体附加到新上下文

dbContext.Set<entity>().Attach(entity);
if (typeFromCombobox.Id == 0){
    //new type added
    dbContext.Set<type>().Add(typeFromCombobox)
}
entity.type = typeFromCombobox;
dbContext.SaveChanges()