我正在使用实体框架4和WPF与MVVM模式。现在我面对可怕的
无法定义两个对象之间的关系,因为 它们附加到不同的ObjectContext对象
消息。我知道它的原因,但我似乎无法弄清楚如何解决它。
这是我想要实现的目标(简化)。在我的应用程序的左侧,我有一个关联列表。然后我选择一个单独的,为该关联创建一个新的Context(我不希望在应用程序的生命周期中使用单个上下文,因为可以打开多个窗口并且可能导致问题。所以它是一个窗口一个上下文)并更新很多字段(大多数类型为DateTime),工作正常。数据绑定,更新数据库等.... 但是,我还有一个组合框,我需要从一组Contact对象中选择关联的主席。出于性能原因,我通过ObjectContext在应用程序启动时加载了一次所有联系人。 我的Comite EntityObject有一个名为President of Contact的导航属性。 Combobox的SelectedItem与Comite.President绑定如下:
<ComboBox Grid.Row="0" Grid.Column="1" ItemsSource="{Binding Contacts}" DisplayMemberPath="FullName" SelectedItem="{Binding Path=Comite.President}" VerticalAlignment="Center"/>
每当我从组合框中选择一个项目时,抛出上述异常,我无法弄清楚原因。我禁用了所有的Context.SaveChanges()调用。我尝试处理PropertyChanging和PropertyChanged事件。我尝试处理Association.PresidentReference.AssociationChanged事件但没有被调用。此处的IDE生成代码发生异常:
[XmlIgnoreAttribute()]
[SoapIgnoreAttribute()]
[DataMemberAttribute()]
[EdmRelationshipNavigationPropertyAttribute("GestionSyndicatsDeChasse", "FK_Comite_ContactsPresident", "Contacts")]
public Contacts President
{
get
{
return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Contacts>("GestionSyndicatsDeChasse.FK_Comite_ContactsPresident", "Contacts").Value;
}
set
{
//Exception is thrown here!
((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Contacts>("GestionSyndicatsDeChasse.FK_Comite_ContactsPresident", "Contacts").Value = value;
}
}
我不想因为VS正在生成该代码而发脾气。
如果我从关联来源的相同上下文中重新创建联系人集合,问题可以解决,但这是一个巨大的性能打击,我不想避免它,因为每次我选择另一个关联,我还需要重新创建联系人集合(从上下文查询)
所以我的问题是:如何从组合框中选择要与总统NavigationProperty相关联的联系人?我不知何故需要将联系人附加到正确的上下文中,但我无法做到这一点。代码没有到达我的任何断点。
以下是异常的Stacktrace:
at System.Data.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedTarget,Boolean applyConstraints,Boolean addRelationshipAsUnchanged,Boolean relationshipAlreadyExists,Boolean allowModifyingOtherEndOfRelationship,Boolean forceForeignKeyChanges) 在System.Data.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedEntity,Boolean applyConstraints)at System.Data.Objects.DataClasses.EntityReference
1.set_ReferenceValue(IEntityWrapper value) at System.Data.Objects.DataClasses.EntityReference
1.set_Value(TEntity 价值) GestionSyndicatsDeChasse.Model.Comite.set_President(Contacts value)in C:\ Documents and Settings \ Administrator \ my documents \ visual studio 2010 \项目\ CDD \ GestionSyndicatsDeChasse \ GestionSyndicatsDeChasse \型号\ ChasseModel.Designer.cs:行 685
此外,在调试器中,我想检查调用Stack。不幸的是,除了发生错误的代码行之外,其他一切都是“外部代码”
我希望有人能在这里帮助我。
答案 0 :(得分:0)
您可能不得不拆分SelectedItem绑定。我之前在MVVM中做过这个没有太多问题。在VM上创建一个属性,该属性镜像基础模型类上的属性值。让我们使用您的总统示例。 Comite和VM(我将在下文中将其称为ComiteViewModel)将具有President属性。 ComiteViewModel应该能够检索对Contact和Comite实体所属的上下文的引用。
在ViewModel上的属性Setter中,在将值推送到实体之前,将其从上下文中分离,将其附加到Comite上下文,将其设置为已修改,进行更改(实际上我认为这两个步骤可以进入任何顺序),并保存更改,然后您可能刷新Comite实体只是为了温暖和模糊。您可能需要在之后分离并重新连接到Contacts上下文。
以下只是一个模型。我目前没有正确访问示例,但它应该给你一些想法。
Public Property President As EPresident
Get
Me.MyComite.President()
End Get
Set(ByVal value As EPresident)
Dim osm As ObjectStateManager = MyContext.ObjectStateManager
MyContext()
ContactContext.Detatch(value)
MyContext.Attach(value)
osm.ChangeObjectState(value, EntityState.Modified)
MyComite.President = value
MyContext.SaveChanges()
End Set
End Property