Я играю с небольшим приложением VB.NET с WPf / MVVM и ADO.NET EF на SQL Express-DB, и у меня возникают проблемы при попытке обновить связанные объекты:
В моей БД есть три таблицы «tb_Actors», «tb_Movies» и таблица соединений «tb_movies_actors».Дизайнер EF создает две сущности «Актеры» и «Фильмы» и правильно устанавливает их свойства навигации на основе внешних ключей.Так что смог создать представление, которое связывается со свойством viewModels, которое имеет все «Movies.Actors».
Сетка данных в моем представлении правильно отображает всех актеров, и - если это новый актер, которого нет в моей БД, - я могу добавить новых актеров в фильм и правильно сохранить изменения в БД.
Однако, если я хочу добавить актера в фильм, который уже находится в моей БД, я получу двойную запись в моей таблице tb_actors.Сначала я установил поля первичного ключа (name и id) в UNIQUE, но затем мой код ломается.Затем я добавил небольшую процедуру обновления, которая проверяет для каждого связанного актера фильма, является ли он известным актером, и заменяет идентификатор «новых актеров» на идентификатор «старых актеров» - это также прерывается.
Есть ли способ сообщить EF, что он должен определить, находится ли добавленный связанный объект (= уже известный актер, добавленный в фильм), уже в БД, и поэтому он должен вставлять только новую запись в соединительную таблицу, но нек таблице связанных объектов?
Моим следующим шагом будет отсоединение связанных объектов и выполнение всех обновлений / вставок в моем собственном коде доступа к данным… но, поскольку я считаю, что моя проблема связана с типичным сценарием использования EF, необходимобыть более элегантным способом обработки обновлений связанных объектов.
Любые мысли, ответы и советы приветствуются!
* РЕДАКТИРОВАТЬ Вот соответствующие фрагменты кода *
1) У меня есть следующая функция LoadMovies в моем классе доступа к данным MovieRepository:
Private Function LoadMovies() As List(Of Movies)
movs = From m In dc.Movies.Include("Actors") Select m
Return movs.ToList
End Function
2) Следующее свойство моего viewModel представляет актеров, связанных с определенным фильмом:
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) В моем представлении MovieDetail у меня есть привязка сетки данных к свойству:
<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) Это мойФункция updateMovie моего MovieRepository (как сейчас):
Public Sub UpdateMovie(ByVal movie As Movies)
If movie Is Nothing Then
Throw New ArgumentNullException("Movie")
Else
dc.SaveChanges()
End If
End Sub