views:

441

answers:

2

Hi All,

I am using EF (Framework 3.5 SP1) and have a simple two table demo set up:

Applicants

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

CodeLanguages

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

A CodeLanguage entry can have 0, 1, * Applicants

Each language ref in Applicants must have 1 (and only one) CodeLanguage ref.

Problem: When I bring back an Applicant entity (via WCF web service to my WPF-based client), if all three language references (coorespondence, exam, and interview) are all the same, lets say 1000 (english), and then I modify one of them, for example to 1001 (french), then all THREE will be changed to 1001 (french).

Here's the weird part: If all three references are different (lets say coorespondence=english, exam=french, and interview=spanish) and I change one of them - then it behaves as expected and only the one I changed is affected - the others are remain in their original state.

I have spent most of today trying various things such as dropping and recreating associations in the EDMX, recreating the EDMX datamodel - even creating a new database. None of this worked - I'm beginning to thing the issue is with EF and not my code.

Any ideas? Thanks.

A: 

Well you are right this does sound very wierd.

I tried to repro your problem based on what you've explained, but couldn't.

If you have a small repro though I will look into this.

If you want you can email me (alexj) @ microsoft.com.

Alex James

Program Manager Entity Framework Team

Alex James
Alex - have emailed you with detailed description
Gatmando
A: 

An update on the final outcome of this issue. After some very quick and helpful advice from the EF team at Microsoft it was determined that this is expected behaviour from EF 3.5 SP1:

"When you query within the service layer for the Applicant where all languages are the same you end up with two objects, one Applicant with all three navigation properties pointing to the same CodeLanguage object.WCF then re-creates this same graph on the client meaning that the three breakpoints you set are indeed looking at the same property on the same object"

Microsoft provided the basis for my ultimate solution which is this:

First: Create a Partial Class for the Applicants data object and create three properties which reference the three language code_ids:

Partial Public Class Applicants

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

End Class

Second: Recompile and refresh the client's service reference. Use the three language code_id properties to bind to controls in xaml

Third: In the server-side update run the following to update the applciant and its language foreign keys:

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()
Gatmando