Entity Framework - странная проблема с несколькими внешними ключами, сопоставленными с одной и той же таблицей - PullRequest
2 голосов
/ 05 августа 2009

Я использую EF (Framework 3.5 с пакетом обновления 1 (SP1)), и у меня настроено простое демо с двумя таблицами:

Кандидаты

  • идентификатор заявителя int
  • Applicant-Pref-Lang-Coorepondence Int (от FK до CodeLanguages)
  • заявитель-pref-lang-exam int (от FK до CodeLanguages)
  • заявитель-преф-ланг-интервью int (от FK до CodeLanguages)

CodeLanguages ​​

  • code-lang-id int
  • код-lang-desc varchar

Запись CodeLanguage может иметь 0, 1, * Претенденты

Каждый языковой реф в Заявителях должен иметь 1 (и только один) код CodeLanguage ref.

Проблема: Когда я возвращаю сущность Кандидата (через веб-сервис WCF к моему клиенту на основе WPF), если все три языковых ссылки (переписка, экзамен и собеседование) одинаковы, скажем, 1000 (английский), а затем я изменяю один из них, например, 1001 (французский), тогда все три будут изменены на 1001 (французский).

Вот странная часть: если все три ссылки разные (скажем, coorespondence = english, экзамен = французский, и интервью = испанский), и я изменяю одну из них - тогда она ведет себя, как и ожидалось, и затрагивается только та, которую я изменила - остальные остаются в своем первоначальном состоянии.

Я потратил большую часть сегодняшнего дня, пробуя различные вещи, такие как удаление и воссоздание ассоциаций в EDMX, воссоздание модели данных EDMX - даже создание новой базы данных. Ничего из этого не сработало - я начинаю понимать, что проблема в EF, а не в моем коде.

Есть идеи? Спасибо.

Ответы [ 2 ]

1 голос
/ 07 августа 2009

Обновленная информация об окончательном результате этого выпуска. После некоторых очень быстрых и полезных советов от команды EF в Microsoft было установлено, что это ожидаемое поведение от EF 3.5 SP1:

"Когда вы запрашиваете в слое обслуживания для Заявителя, где все языки одинаковы, вы получаете два объекта, один Заявитель со всеми тремя свойствами навигации, указывающими на один и тот же объект CodeLanguage. Затем WCF создает его заново тот же график на клиенте, означающий, что три заданные вами точки останова действительно смотрят на одно и то же свойство одного и того же объекта "

Microsoft предоставила основу для моего окончательного решения, а именно:

Первое: Создайте частичный класс для объекта данных Applicants и создайте три свойства, которые ссылаются на три языка 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()
0 голосов
/ 06 августа 2009

Ну, вы правы, это звучит очень странно.

Я пытался воспроизвести вашу проблему, основываясь на том, что вы объяснили, но не смог.

Если у вас есть небольшое репро, хотя я посмотрю на это.

Если хотите, можете написать мне (alexj) @ microsoft.com.

Алекс Джеймс

Руководитель программы Entity Framework Team

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...