C# 无法获取相关的父实体对象&;将其添加到ObjectContext
在成功添加父实体对象的相关子实体对象后,我当前难以跟踪该对象并将其添加到上下文中 我有两个SQL表映射到通过外键关联的实体:C# 无法获取相关的父实体对象&;将其添加到ObjectContext,c#,entity-framework-4,parent-child,observablecollection,savechanges,C#,Entity Framework 4,Parent Child,Observablecollection,Savechanges,在成功添加父实体对象的相关子实体对象后,我当前难以跟踪该对象并将其添加到上下文中 我有两个SQL表映射到通过外键关联的实体: MasterPartNumber (parent, one) --> MasterPartsList (children, many) (PK) pn <--short for PartNumber (PK) listID pnDesc (FK) pn docNum
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
选定的父部件由viewmodel特性定义:
public MasterPartNumber SelectedTopLevelAssyPN
{
get { return this._selectedTopLevelAssyPN; }
set
{
this._selectedTopLevelAssyPN = value;
RaisePropertyChanged("SelectedTopLevelAssyPN");
RaisePropertyChanged("SelectedAssyBOMLineItems");
}
}
当用户单击一个选定的父程序集(SelectedTopLevelAssyPN
)时,数据网格将显示绑定到其父级(由属性parentAssyPN
给定)为SelectedTopLevelAssyPN
的所有子实体的observedcollection
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");
}
}
如果不是因为MasterPartNumber.pn
上的强制外键约束(该约束不能为空),这看起来实际上会保存我的MasterPartsList数据
这件事我已经坚持了好几天了。当我只处理一个表时,我很容易实现.SaveChanges。有人知道我为什么不能添加item.MasterPartNumber
(或者甚至不能获取非空对象吗?)
提前谢谢。请告诉我需要进一步澄清的地方。首先,我不建议将数据加载到属性getter中 其次,当您添加
项目时,是否应该自动将项目.MasterPartNumber
等实体引用添加到上下文中?我相信这是EF的常见工作方式
您还提到强制外键约束。。。那部分不太清楚。你能提供例外信息吗?另外,您使用的版本/风格是-DbContext还是ObjectContext?代码优先?自跟踪实体?问题出在外键还是主键上?主键是否自动递增并在数据库和EDMX中标记为自动递增
作为一般性建议,请确保您试图理解实体框架在封面下所做的工作;否则,你最终会在没有真正理解原因的情况下讨厌它(不是因为没有充分的理由)。试着想象一下你记忆中的对象图,以及EF如何跟踪所有事物的连接方式;当您保存更改并试图确定保存所有内容所需的顺序时,它就会这样做,这样就不会违反约束。啊,但我会停止诗意化,因为我还能保持严肃的外表。谢谢,亚历克斯。关于我的问题的所有其他问题都放在一边:如果item.MasterPartNumber不是自动的。当我添加项时,添加到上下文中,您认为我的实体关系有什么问题?我认为这才是整件事的根本原因。如果你不介意的话,请在问题的开头看看我的SQL表;假设你把一切都安排好了,没有理由不这样做。但是,您可以放置一些跟踪代码来帮助您:类似于\u context.Entry(item.MasterPartNumber)。State
以查看这是否真的是问题所在。你在做其他可能会干扰的事情吗?ParentAssyPN是否设置为一种关系?“没有更多的信息,我就帮不了什么忙了……谢谢,”亚历克斯·帕文说。我有更多的信息/我将继续努力完善这个问题。如果您愿意,请稍后在更新时查看—您似乎是一个很好的资源。
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");
}
}
<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>
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();
}
}