Synchronisation propriete navigation entity framework
Bonjour,
Concernant le contexte, je développe une appli WPF en VB.net avec EF 6.2.0.
J'essaie de mettre à jour une clé étrangère via une combobox, mais lorsque je fais SaveChanges, j'obtiens une erreur "A referential integrity constraint violation occurred: The property value(s) of 'RefTypeCompetition.RefTypeCompetitionId' on one end of a relationship do not match the property value(s) of 'Competition.TypeCompetitionId' on the other end".
Quand je debug, je vois que competition.TypeCompetitionId a bien la valeur que je viens de définir, mais je vois aussi que la propriété de navigation n'est pas en adéquation avec le TypeCompetitionId.
Pour charger les données je procède comme suit :
Code:
1 2 3 4 5 6
|
Using ctx As New myContext
For Each competition As Competition In ctx.Competitions.Include("TypeCompetition").OrderByDescending(Function(f) f.DateDebut)
LastCompetitions.Add(competition)
Next
End Using |
Ensuite, pour la mise à jour de ma clé étrangère j'utilise une combobox décrite comme ceci :
Code:
1 2
| <ComboBox ItemsSource="{Binding TypesCompetition}" HorizontalAlignment="left" Width="350" HorizontalContentAlignment="left" DisplayMemberPath="Libelle" SelectedValuePath="RefTypeCompetitionId" SelectedValue="{Binding Competition.TypeCompetitionId, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" /> |
Puis pour sauvegarder :
Code:
1 2 3 4 5 6 7 8
| Private Sub OnSaveCompetitionCommand()
Using ctx As New MyContext
'on attache la compet existante au contexte
ctx.Competitions.Attach(_Competition)
ctx.Entry(_Competition).State = Entity.EntityState.Modified
ctx.SaveChanges()
End Using
End Sub |
Ma classe compétition se prséente comme ceci :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| Public Class Competition
Inherits ObservableObject
Public Property CmpGuid As Guid
Private _Nom As String
Public Property Nom As String
Get
Return _Nom
End Get
Set(value As String)
_Nom = value
OnPropertyChanged(NameOf(Nom))
End Set
End Property
Public Property TypeCompetitionId As Integer
Private _TypeCompetition As RefTypeCompetition
Public Property TypeCompetition As RefTypeCompetition
Get
Return _TypeCompetition
End Get
Set(value As RefTypeCompetition)
_TypeCompetition = value
OnPropertyChanged(NameOf(TypeCompetition))
End Set
End Property
End Class |
Et la classe RefTypeCompetition
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| Public Class RefTypeCompetition
Public Property RefTypeCompetitionId As Integer
Public Property Libelle As String
Public Property TypeEpreuve As TypeEpreuve
Public Property Competitions As ObservableCollection(Of Competition)
End Class |
Au cas où, je mets aussi mon context :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| Public Class MyContext
Inherits DbContext
#Region "DBSets"
Public Property Competitions As DbSet(Of Competition)
#Region "Référentiels"
Public Property RefTypesCompetitions As DbSet(Of RefTypeCompetition)
#End Region
#End Region
Public Sub New()
MyBase.New("myConnection")
Database.SetInitializer(New MigrateDatabaseToLatestVersion(Of MyContext, Models.Migrations.Configuration))
End Sub
Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
MyBase.OnModelCreating(modelBuilder)
modelBuilder.Conventions.Remove(Of PluralizingTableNameConvention)()
' ******************************************************** référentiels **************************************************************************
With modelBuilder.Entity(Of RefTypeCompetition)
.HasKey(Function(c) c.RefTypeCompetitionId)
.Property(Function(c) c.RefTypeCompetitionId).HasDatabaseGeneratedOption(ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)
.HasMany(Function(f) f.Competitions).WithRequired(Function(f) f.TypeCompetition).HasForeignKey(Function(f) f.TypeCompetitionId)
End With
' ************************************************************************************************************************************************
With modelBuilder.Entity(Of Competition)
.HasKey(Function(c) c.CmpGuid)
.Property(Function(c) c.CmpGuid).HasDatabaseGeneratedOption(ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)
.HasMany(Function(f) f.Epreuves).WithRequired(Function(f) f.Competition).WillCascadeOnDelete()
'.HasRequired(Function(f) f.TypeCompetition).WithMany(Function(f) f.Competitions).HasForeignKey(Function(f) f.TypeCompetitionId)
End With
End Sub
End Class |
J'ai remarque que dans ma Sauvegarde, si je fais ceci :
Code:
1 2 3 4 5 6 7
| Using ctx As New MyContext
'on attache la compet existante au contexte
ctx.Competitions.Attach(_Competition)
_Competition.TypeCompetitionId = 1
ctx.Entry(_Competition).State = Entity.EntityState.Modified
ctx.SaveChanges()
End Using |
Là tout fonctionne ... mais ce n'est pas ce que je veux, puisque dans ce cas, je met la valeur en dur.
Je dois surement faire un truc de travers, mais je ne vois pas quoi.
Merci d'avance.