实体框架 - 将多个外键映射到同一个表的奇怪问题

时间:2009-08-05 19:43:00

标签: entity-framework

我正在使用EF(Framework 3.5 SP1),并设置了一个简单的两个表演示:

申请人

  • applicant-id int
  • applicant-pref-lang-coorepondence int(FK to CodeLanguages)
  • applicant-pref-lang-exam int(FK to CodeLanguages)
  • 申请人 - pref-lang-interview int(FK to CodeLanguages)

CodeLanguages

  • code-lang-id int
  • code-lang-desc varchar

CodeLanguage条目可以包含0,1,*申请人

申请人中的每种语言参考号必须包含1个(且仅限1个)CodeLanguage参考号。

问题: 当我带回申请人实体(通过WCF Web服务到我的基于WPF的客户端)时,如果所有三种语言引用(coorespondence,exam和interview)都是相同的,那么让我们说1000(英语),然后我修改一个其中,例如1001(法国),那么所有三个将改为1001(法语)。

这是奇怪的部分:如果所有三个引用都不同(假设coorespondence =英语,考试=法语,面试=西班牙语)并且我改变其中一个 - 那么它的行为与预期一致,只有我改变的那个受到影响 - 其他人保持原状。

我今天大部分时间都在尝试各种各样的事情,比如在EDMX中删除和重新创建关联,重新创建EDMX数据模型 - 甚至创建一个新的数据库。这些都不起作用 - 我开始认为问题出在EF上,而不是我的代码。

有什么想法吗?感谢。

2 个答案:

答案 0 :(得分:1)

此问题的最终结果的更新。在Microsoft的EF团队提供了一些非常快速和有用的建议之后,确定这是EF 3.5 SP1的预期行为:

“当您在服务层内查询所有语言相同的申请人时,您最终得到两个对象,一个申请人将所有三个导航属性指向同一个CodeLanguage对象.WCF然后重新创建此客户端上的相同图表意味着您设置的三个断点确实在同一对象上查看相同的属性“

Microsoft为我的最终解决方案提供了基础:

首先:为申请人数据对象创建一个部分类,并创建三个引用三种语言code_ids的属性:

部分公共类申请人

Private _intPrefCoorespLanguage As Integer = 0

Private _intPrefInterviewLanguage As Integer = 0

Private _intPrefExamLanguage As Integer = 0

<System.Runtime.Serialization.DataMemberAttribute()> _
Public Property MyPrefCoorespLanguageCodeId() As Integer
    Get
        Return (_intPrefCoorespLanguage)
    End Get
    Set(ByVal value As Integer)
        _intPrefCoorespLanguage = value
    End Set
End Property

<System.Runtime.Serialization.DataMemberAttribute()> _
Public Property MyPrefInterviewLanguageCodeId() As Integer
    Get
        Return (_intPrefInterviewLanguage)
    End Get
    Set(ByVal value As Integer)
        _intPrefInterviewLanguage = value
    End Set
End Property

<System.Runtime.Serialization.DataMemberAttribute()> _
Public Property MyPrefExamLanguageCodeId() As Integer
    Get
        Return (_intPrefExamLanguage)
    End Get
    Set(ByVal value As Integer)
        _intPrefExamLanguage = value
    End Set
End Property


<OnSerializing()> _
Private Sub PopulateClientProperties(ByVal sc As StreamingContext)
    Me.MyPrefCoorespLanguageCodeId = Me.PrefCoorespLanguage.code_lang_id
    Me.MyPrefInterviewLanguageCodeId = Me.PrefInterviewLanguage.code_lang_id
    Me.MyPrefExamLanguageCodeId = Me.PrefExamLanguage.code_lang_id
End Sub

结束班

第二:重新编译并刷新客户端的服务参考。使用三种语言的code_id属性绑定到xaml中的控件

第三:在服务器端更新中运行以下命令以更新applciant及其语言外键:

myContext = New HR2009Entities

'Get original Applicant and feed in changes from detatched updated Applicant object
Dim OrigApp = (From a In myContext.Applicants Where a.applicant_id = pobjUpdatedApplicant.applicant_id Select a).First

'Apply preferred language foreign key refs
OrigApp.PrefCoorespLanguageReference.EntityKey = _
   New EntityKey("HR2009Entities.CodeLanguages", "code_lang_id",pobjUpdatedApplicant.MyPrefCoorespLanguageCodeId)

OrigApp.PrefInterviewLanguageReference.EntityKey = _
   New EntityKey("HR2009Entities.CodeLanguages", "code_lang_id", pobjUpdatedApplicant.MyPrefInterviewLanguageCodeId)

OrigApplicant.PrefExamLanguageReference.EntityKey = _
   New EntityKey("HR2009Entities.CodeLanguages", "code_lang_id", pobjUpdatedApplicant.MyPrefExamLanguageCodeId)

'Apply Applicant table native-field changes
myContext.ApplyPropertyChanges(OrigApp.EntityKey.EntitySetName, pobjUpdatedApplicant)

'Save to database
myContext.SaveChanges()

myContext.Dispose()

答案 1 :(得分:0)

嗯,你说得对,听起来非常奇怪。

我试图根据您所解释的内容重新调试您的问题,但不能。

如果你有一个小的复制品,我会调查一下。

如果您愿意,可以给我发电子邮件(alexj)@ microsoft.com。

亚历克斯詹姆斯

项目经理实体框架小组