Определите, нужно ли сохранять отдельные объекты в EF4 и WPF - PullRequest
0 голосов
/ 21 апреля 2011

Я пытаюсь определить, есть ли у сущности в EF4 изменения, которые нужно сохранить.

Через несколько лет после .NET ржавый - это определенно то слово, которое я бы использовал, чтобы описать, где я сейчас нахожусь.Я пытаюсь научиться использовать EF4 и WPF при повторном знакомстве с .NET.Я следовал нескольким учебникам по привязке данных Drag & Drop с помощью Entity Framework и WPF и создал приложение с несколькими Windows, которое постепенно расширяет мои знания.

Я использую простейшую частьМоя модель для моих тренировочных упражнений. Модель имеет сущности: Сеть и Лаборатория, между Сетями и Лабораториями существует связь «многие ко многим», а именно NetworkLabs, отношения не особенно важны сейчас, так как я все еще нахожусь на самых основах.

У меня есть окно, в котором в списке отображается список сетей, а рядом с ним находится DataGrid, в котором отображаются лаборатории в сети.Я смог сделать это довольно легко, следуя инструкциям, и в итоге получил код, подобный следующему:

Public Class NetworkListWindow

Private Function GetNetworksQuery(entities As UKNEQASEntities) As ObjectQuery(Of Network)

    Dim networksQuery As ObjectQuery(Of Network) = entities.Networks
    ' Update the query to include NetworkLabs data in Networks.
    networksQuery = networksQuery.Include("NetworkLabs")
    ' Returns an ObjectQuery
    Return networksQuery

End Function

Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded

    Dim entities As UKNEQASEntities = New UKNEQASEntities()
    ' Load data into Networks.
    Dim networksViewSource As CollectionViewSource = CType(Me.FindResource("UKNEQASEntitiesNetworksViewSource"), CollectionViewSource)
    Dim networksQuery As ObjectQuery(Of Network) = GetNetworksQuery(entities)
    networksViewSource.Source = networksQuery.Execute(MergeOption.AppendOnly)

End Sub

End Class

Это окно предназначено только для просмотра, пользователь может нажать кнопку редактирования, чтобы редактировать выбранную сеть.Во втором окне я сталкиваюсь с проблемами. В этом окне я перетащил сетевой объект из окна Источники данных, чтобы создать экран сведений (сетка с метками и текстовыми полями в строках и столбцах).В итоге я получил код, подобный следующему:

Public Class NetworkWindow

Private m_id As Integer
Private m_db As New UKNEQASEntities

Public Sub New(id As Integer)

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    m_id = id

End Sub

Private Function GetNetworkQuery() As ObjectQuery(Of Network)

    Dim networkQuery As ObjectQuery(Of Network) = m_db.Networks
    ' Update the query to include only the Network we are editing
    networkQuery = networkQuery.Where(Function(net) net.Id = m_id)
    ' Update the query to include NetworkLabs data in Networks.
    networkQuery = networkQuery.Include("NetworkLabs")
    ' Returns an ObjectQuery
    Return networkQuery

End Function

Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded

    ' Load data into Networks.
    Dim networkViewSource As CollectionViewSource = CType(Me.FindResource("UKNEQASEntitiesNetworksViewSource"), CollectionViewSource)
    Dim networksQuery As ObjectQuery(Of Network) = GetNetworkQuery()
    networkViewSource.Source = networksQuery.Execute(MergeOption.AppendOnly)

    ' Get laboratories that are not in any networks
    Dim labResult = From laboratory In m_db.Laboratories _
                    Where _
                    Not _
                    (From networklab In m_db.NetworkLabs _
                     Select networklab.Laboratory.Id).Contains(laboratory.Id) _
                    Select laboratory

    Dim laboratoriesViewSource As CollectionViewSource = CType(Me.FindResource("UKNEQASEntitiesLaboratoriesViewSource"), CollectionViewSource)
    laboratoriesViewSource.Source = labResult.ToList

End Sub

End Class

И это прекрасно работает для отображения сети, выбранной на предыдущем экране, я поместил кнопку «Сохранить» на панель инструментов, которая просто вызывает

m_db.SaveChanges()

Сохранить изменения, и это тоже хорошо работает.Моя проблема возникает, когда пользователь обрабатывает данные, когда пользователь редактирует данные и закрывает окно, и я хочу определить, нуждается ли текущая сеть в сохранении обратно в базу данных, чтобы я мог подсказать пользователю, но не знаю, как получить доступ к сети.чтобы проверить.

Я подозреваю, что это как-то связано с кодом, подобным:

     Dim networkViewSource As CollectionViewSource = CType(Me.FindResource("UKNEQASEntitiesNetworksViewSource"), CollectionViewSource)
     Dim entry As ObjectStateEntry = m_db.ObjectStateManager.GetObjectStateEntry(....)

, но я не знаю, как заставить сеть передать GetObjectStateEntry.

На моем предыдущем экране списка я смог получить выбранную сеть, получив SelectedItem из списка, но я не могу найти ничего, что могло бы помочь мне в моем окне единой записи.

Я собираюсь сделать этоправильно?Для экрана редактирования однократной записи я все еще использую CollectionViewSource, как и для экрана списка, это лучший способ или есть что-то для отдельных объектов?

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

Любая помощь очень ценится, так как я новичок вэтот EF и XAML жаворонок.

1 Ответ

0 голосов
/ 21 апреля 2011

Вы смотрите на это с неправильной точки зрения. Несколько вещей, которые вам нужно учитывать, когда вы начинаете использовать EF:

  • Вам не нужно смотреть на ObjectStateManager, это что-то EF должен сделать для вас. Например, если вы хочу закрыть окно и сохранить все, просто позвони context.SaveChanges () и пусть EF работа по выяснению того, что нужно экономия а что нет. Есть случаи, когда вам нужно использовать ObjectStateManager, но они специфичны и обычно связаны с очень нестандартными вещами.

  • Вы не видите много примеров, потому что люди, которые строят WPF и приложения Silverlight не подключен к базам данных, вместо этого они подключаются к одному или нескольким слои веб-сервисов и взаимодействия с ними. Когда вы делаете это, Первое, что происходит, это то, что вы нет дольше работать с "нормальным" EF сущности, они не были созданы сериализованная. Вы будете работать с любым POCO Сущности самостоятельного отслеживания Сущности.

  • Если вы используете обычные сущности, они предназначены для постоянной работы привязан к контексту (в вашем случае это будет: UKNEQASEntities), это означает, что если вы попытаетесь использовать это в клиентском приложении вы захотите чтобы вы всегда использовали одно и то же контекст, так что либо есть ссылка к нему в классе Singleton или вводить это в инъекции зависимости контейнер. Если вы используете несколько контексты вы встретите кучу проблем, связанных с EntityKeys, которые предоставляются объектам по отношению к контексту они существуют в (рассмотреть контекст памяти копия вашей базы данных, это не правда на практике, это работает больше как интерфейс, который вы используете для автоматически генерировать SQL-запросы против ваша база данных.

В конце концов, если вы хотите создать хорошее клиентское приложение WPF, вам также необходимо использовать:

  • Контейнер для инъекций зависимости: либо MEF (который развернут на развертывание .Net) или Unity (который является частью предприятия Библиотека).
  • EF4 Самостоятельно отслеживаемые объекты (I лично предпочитаю это над POCO объекты, потому что вы получаете много мощный функционал бесплатно).

Вы также можете указать мне напрямую, если вам нужна более конкретная помощь, я уже некоторое время работаю над этим, в профессиональных командах разработчиков в средних и крупных проектах. Однако я никогда не работал в Visual Basic, поэтому мне немного больно, когда мне приходится читать код VB!

...