【问题标题】:Add new child entity and update parent entity in one turn一次性添加新的子实体和更新父实体
【发布时间】:2017-03-29 07:41:36
【问题描述】:

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

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

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

我如何将类型绑定到 Combobox:

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

typeTableController 有一个属性 (AllTypes) 包含数据库中的所有现有类型。 Entry 是当前选择的entry。用户现在可以编辑 ComboBox 文本。如果他按下“保存”按钮,如果该类型尚不存在,则应将其添加到数据库中,或者如果存在则应选择该类型。并且应该保存更新的条目。如果我不必自己处理每个属性,那就太好了,因为 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 添加到类型表中但也复制类型/条目表中的所有类型和条目(这对我来说真的很奇怪)并且只更新现在两个现有 @987654337 之一的类型@给新的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。似乎这会导致一些冲突。删除它可以解决这个问题。

【问题讨论】:

    标签: c# entity-framework combobox foreign-key-relationship invalidoperationexception


    【解决方案1】:

    确定类型是现有的还是用户新添加的。检查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()
    

    编辑:不确定:您正在使用组合框绑定,当用户选择它时应该自动更改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()
    

    【讨论】:

    • 使用您的代码,将添加新类型。但是条目的外键没有在数据库中更新。我不确定你所说的“分离”是什么意思。我不再处于加载条目时创建的上下文中。
    • @L3n95 你的意思是entry.typeId 外键?通常,当您分配导航属性时,EF 应该处理此问题
    • 是的。更新前:entry.type_id = 55,entry.type.id = 0;更新后:entry.type_id = 55, entry.type.id = 56
    • @L3n95 在您的应用程序中_idid 有什么区别?似乎 EF 可以正常使用 id 字段,但不知道 _id
    • 类条目具有属性:public Nullable type_id 和属性:public virtual type type,它本身具有属性 id。这是由实体框架创建的。所以entry中存在type_id,type中存在type.id。
    猜你喜欢
    • 2015-01-26
    • 1970-01-01
    • 2019-12-05
    • 2013-03-03
    • 1970-01-01
    • 2013-07-24
    • 2011-12-19
    • 1970-01-01
    • 2018-06-29
    相关资源
    最近更新 更多