views:

39

answers:

0

Hi experts,

I’m playing around with a little VB.NET app with WPf/MVVM and ADO.NET EF on a SQL Express-DB and I’m running into problems while trying to update related objects:

My DB has three tables “tb_Actors”, “tb_Movies” and a junction table “tb_movies_actors”. The EF designer creates two entities "Actors" und "Movies" and sets their navigation properties based on the foreign keys correctly. So was able to come up with a view which binds to a viewModels property which has all “Movies.Actors”.

The DataGrid in my view displays all actors correctly, and – if it’s a new actor which isn’t in my DB already- I am able to add new actors to a movie and persist the changes to the DB correctly.

However, if I want to add an actor to a movie who is already in my DB, I’ll get a double entry in my tb_actors table. First I’ve set the primary key fields (name and id) to UNIQUE, but then my code breaks. Then, I’ve added a little update routine which checks for each related actor of a movie if it’s a known actor, and changes the “new actors” id to the “old actors” id – this also breaks.

Is there a way to tell EF that it has to determine if an added related object (= already known actor added to movie) is already in the DB, and it therefore has to insert only a new entry to to junction table, but not to the related objects table?

My next step would be detaching the related objects and do all updates/inserts in my own data access code … but since I believe my problem is around a typical EF use case, there must be a more elegant way to deal with updates on related objects.

Any thoughts, answers, hints are highly appreciated!

* EDIT Here are the relevant code snippets *

1) I have the following LoadMovies Function in my MovieRepository data access class:

Private Function LoadMovies() As List(Of Movies)
        movs = From m In dc.Movies.Include("Actors") Select m
        Return movs.ToList
End Function

2) The following property of my viewModel exposes the actors related to a specific movie:

        Public ReadOnly Property actors() As ICollectionView
        Get
            If evs Is Nothing Then
                evs = New CollectionViewSource
                evs.Source = _movie.Actors
            End If
            Return evs.View
        End Get
        End Property

3) In my MovieDetail view, I've a datagrid binding to the property:

<DataGrid Name="ActTestGrid" HorizontalAlignment="Left" VerticalAlignment="Stretch" ItemsSource="{Binding actors}" AutoGenerateColumns="False" Width="150" Height="120" Style="{StaticResource dgTemplate}" RowStyle="{StaticResource dgRowTemplate}" CellStyle="{StaticResource dgCellTemplate}" CanUserSortColumns="True" CanUserAddRows="True" CanUserDeleteRows="True" HeadersVisibility="None">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Name" Binding="{Binding Path=name, UpdateSourceTrigger=PropertyChanged}" CanUserSort="true"/>
                </DataGrid.Columns>
</DataGrid>

4) This is my updateMovie Function of my MovieRepository (as by now):

Public Sub UpdateMovie(ByVal movie As Movies)
        If movie Is Nothing Then
            Throw New ArgumentNullException("Movie")
        Else

            dc.SaveChanges()
        End If
End Sub