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 :
Ensuite, pour la mise à jour de ma clé étrangère j'utilise une combobox décrite comme ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
Puis pour sauvegarder :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 <ComboBox ItemsSource="{Binding TypesCompetition}" HorizontalAlignment="left" Width="350" HorizontalContentAlignment="left" DisplayMemberPath="Libelle" SelectedValuePath="RefTypeCompetitionId" SelectedValue="{Binding Competition.TypeCompetitionId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
Ma classe compétition se prséente comme ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
Et la classe RefTypeCompetition
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
Au cas où, je mets aussi mon context :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
J'ai remarque que dans ma Sauvegarde, si je fais ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
Là tout fonctionne ... mais ce n'est pas ce que je veux, puisque dans ce cas, je met la valeur en dur.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
Je dois surement faire un truc de travers, mais je ne vois pas quoi.
Merci d'avance.
Partager