在成功添加其相关子项后,我目前难以跟踪父实体对象并将其添加到我的上下文中。
我有两个 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,它显示了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");
}
}
选定的父组件由 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
(或者甚至得到一个非空对象,就此而言?)
提前致谢。请让我知道我需要进一步澄清的地方。