【问题标题】:Unable to grab related parent entity object & add it to the ObjectContext无法抓取相关的父实体对象并将其添加到 ObjectContext
【发布时间】:2013-02-26 00:29:29
【问题描述】:

在成功添加其相关子对象后,我目前难以跟踪父实体对象并将其添加到我的上下文中。

我有两个 SQL 表映射到通过外键关联的实体:

 MasterPartNumber (parent, one) --> MasterPartsList (children, many)
  (PK) pn <--short for PartNumber     (PK) listID
       pnDesc                         (FK) pn
       docNum                              parentAssyPN <-- if null, means it is the "top level assembly"
                                           findNum
                                           qty
                                           isAssy

在视图的左侧,我有一个 ListBox,它显示所有 assemblyparent 实体对象的 ObservableCollection。它看起来像:

    public ObservableCollection<MasterPartNumber> AssyPns
    {
        get
        {
                var enumerable = this._context.MasterPartNumbers.Where(x => x.isAssy == true);

                return this._assyPns = new ObservableCollection<MasterPartNumber>(enumerable);
        }
        set 
        {
            this._assyPns = value;
            RaisePropertyChanged("AssyPns");  
        }
    }

Selected Parent Assembly 由 viewmodel 属性定义:

 public MasterPartNumber SelectedTopLevelAssyPN 
 {
      get { return this._selectedTopLevelAssyPN; }
      set
      {
          this._selectedTopLevelAssyPN = value;
          RaisePropertyChanged("SelectedTopLevelAssyPN");
          RaisePropertyChanged("SelectedAssyBOMLineItems");
      }
  }

当用户单击其中一个选定的父程序集 (SelectedTopLevelAssyPN) 时,DataGrid 会显示绑定到所有子实体的ObservableCollection,其父实体(由属性parentAssyPN 给出)是SelectedTopLevelAssyPN

 public ObservableCollection<MasterPartsList> SelectedAssyBOMLineItems
    {
        get
        {
            if (this._selectedTopLevelAssyPN != null)
            {
                var children = _context.MasterPartsLists.Where(lineItem => lineItem.parentAssyPN == this._selectedTopLevelAssyPN.pn);
                return this._selectedAssyBOMLineItems = new ObservableCollection<MasterPartsList>(children);

            }
            return this._selectedAssyBOMLineItems;
        }
        set
        {
            this._selectedAssyBOMLineItems = value;
            RaisePropertyChanged("SelectedAssyBOMLineItems");
        }
    }

注意我如何能够通过集合属性导航到包含外键的实体(这是我的 xaml):

             <DataGrid x:Name="lineItemDataEntryGrid" Grid.Row="0"
                  Margin="15,15,15,0"
                  AutoGenerateColumns="False"
                  EnableRowVirtualization="True"
                  Width="Auto"
                  ItemsSource="{Binding SelectedAssyBOMLineItems, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                  >
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="qtyReadColumn" 
                                    Binding="{Binding qty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                    Width="SizeToHeader"
                                    Header="QTY REQ'D"/>
                <DataGridTextColumn x:Name="partOrIDNumColumn" 
                                    Binding="{Binding pn, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                    Width="SizeToHeader"
                                    Header="PART OR IDENTIFYING NUMBER"/>

                <DataGridTextColumn x:Name="partNumDescColumn" 
                                    Binding="{Binding MasterPartNumber.pnDesc, Mode= TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                    Width="SizeToHeader"
                                    Header="NOMENCALTURE OR DESCRIPTION"/>
                <DataGridTextColumn x:Name="docNumColumn" 
                                    Binding="{Binding MasterPartNumber.docNum, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                    Width="SizeToHeader"
                                    Header="INTERNAL DOCUMENTATION"/>
                <DataGridTemplateColumn x:Name="isAssyColumn" 
                                        Header="IS ASSEMBLY? "
                                        Width="30"
                                        >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding isAssy}" IsThreeState="False" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

            </DataGrid.Columns>

        </DataGrid>

一切都显示正确。这意味着我有效地将父实体向下导航到子实体。

现在我的问题是:我完全可以将 MasterPartsList 中的新项目添加到 context,但不能添加到 MasterPartNumber 对象。

我的 SaveCommand(中继命令)中的代码如下所示:

    private void SaveLineItems()
    {
        //update the parts list if any Object properties have been edited

        foreach (MasterPartsList item in this._selectedAssyBOMLineItems)
        {
            this._context.DetectChanges();
            this._context.MasterPartsLists.AddObject(item);
          //  this._context.MasterPartNumbers.AddObject(item.MasterPartNumber); //Doesn't work: pnMatch.MasterPartNumber is null & Throws NullReferenceException
            this._context.SaveChanges();
        }
    }     

看来这实际上会保存我的 MasterPartsList 数据,如果不是因为 MasterPartNumber.pn 上的强制外键约束不能为空。

我已经坚持了好几天了。当我只使用一张表时,我很容易实现 .SaveChanges。有谁知道为什么我无法添加item.MasterPartNumber(或者甚至无法获得非空对象?)

提前致谢。请让我知道我需要进一步澄清的地方。

【问题讨论】:

    标签: c# entity-framework-4 parent-child observablecollection savechanges


    【解决方案1】:

    首先,我不建议在属性 getter 中加载数据。

    第二,在添加item时,不应该将item.MasterPartNumber等实体引用自动添加到上下文中吗?我确信这是 EF 的常见工作方式。

    您还提到了强制外键约束……那部分不是很清楚。你能提供异常消息吗?另外,您使用的是什么版本/风格 - DbContext 或 ObjectContext?先码字?自我跟踪实体?问题是外键还是主键?主键是否在数据库和 EDMX 中都自动递增并标记为这样?

    作为一般建议,请确保您尝试了解实体框架在幕后所做的事情;否则你会在没有真正理解原因的情况下最终讨厌它(并不是没有充分的理由)。尝试可视化您在内存中的对象图以及 EF 如何尝试跟踪所有内容的连接方式;当您保存更改并尝试找出保存所有内容所需的顺序时,它会这样做,以免违反约束。啊,但我会在我还能保持一副严肃的样子的时候停止写诗。

    【讨论】:

    • 谢谢,亚历克斯。除了我的问题的所有其他问题:如果 item.MasterPartNumber 不是自动的。添加项目时添加到上下文中,您认为我的实体关系可能有什么问题?我认为这确实是整个事情的根本原因。如果您不介意,请查看问题开头的我的 SQL 表。
    • 真的,我不能只看数据模型;假设您已正确设置所有内容,则没有理由不应该这样做。但是,您可以放置​​一些跟踪代码来帮助您:_context.Entry(item.MasterPartNumber).State 之类的东西,看看这是否真的是问题所在。你在做其他可能干扰的事情吗? ParentAssyPN 是否设置为关系?如果没有更多信息,我将无法提供更多帮助......
    • 谢谢,@Alex Paven。我有更多信息/我将继续努力完善这个问题。如果您愿意,请稍后在更新时查看-您似乎是一个很好的资源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    • 1970-01-01
    • 2019-12-07
    • 2020-10-04
    • 2022-01-19
    • 1970-01-01
    相关资源
    最近更新 更多