关联来自不同对象上下文的对象:不知道在哪里捕获异常

时间:2011-07-20 13:15:43

标签: wpf entity-framework data-binding mvvm

我正在使用实体框架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

此外,在调试器中,我想检查调用St​​ack。不幸的是,除了发生错误的代码行之外,其他一切都是“外部代码”

我希望有人能在这里帮助我。

1 个答案:

答案 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