Лучшие практики для использования Entity Framework с WPF DataBinding

entity-framework wpf

Вопрос

Я нахожусь в процессе создания моего первого реального приложения WPF (то есть, первого, предназначенного для использования кем-то кроме меня), и я все еще обдумываю лучший способ сделать вещи в WPF. Это довольно простое приложение для доступа к данным, использующее все еще довольно новую платформу Entity Framework, но я не смог найти много рекомендаций в Интернете о том, как наилучшим образом использовать эти две технологии (WPF и EF) вместе. Поэтому я подумал, что выброшу, как я к нему подхожу, и посмотрю, есть ли у кого-нибудь лучшие предложения.

  • Я использую Entity Framework с SQL Server 2008. Мне кажется, что EF гораздо сложнее, чем нужно, но еще не достиг зрелости, но Linq-to-SQL, по-видимому, мертв, поэтому я мог бы также использовать эту технологию. что MS, кажется, фокусируется на.

  • Это простое приложение, поэтому я (пока) не счел нужным построить вокруг него отдельный слой данных. Когда я хочу получить данные, я использую довольно простые запросы Linq-to-Entity, обычно прямо из моего кода, например:

    var families = from family in entities.Family.Include("Person")
               orderby family.PrimaryLastName, family.Tag
               select family;
    
  • Запросы Linq-to-Entity возвращают результат IOrderedQueryable, который не отражает автоматически изменения базовых данных, например, если я добавляю новую запись с помощью кода в модель данных объекта, существование этой новой записи автоматически не отражается в различные элементы управления, ссылающиеся на запрос Linq. Следовательно, я добавляю результаты этих запросов в ObservableCollection, чтобы зафиксировать изменения основных данных:

    familyOC = new ObservableCollection<Family>(families.ToList());
    
  • Затем я сопоставляю ObservableCollection с CollectionViewSource, чтобы я мог получать фильтрацию, сортировку и т. Д., Не возвращаясь в базу данных.

    familyCVS.Source = familyOC;
    familyCVS.View.Filter = new Predicate<object>(ApplyFamilyFilter);
    familyCVS.View.SortDescriptions.Add(new System.ComponentModel.SortDescription("PrimaryLastName", System.ComponentModel.ListSortDirection.Ascending));
    familyCVS.View.SortDescriptions.Add(new System.ComponentModel.SortDescription("Tag", System.ComponentModel.ListSortDirection.Ascending));
    
  • Затем я связываю различные элементы управления и что-не с этим CollectionViewSource:

    <ListBox DockPanel.Dock="Bottom" Margin="5,5,5,5" 
        Name="familyList" 
        ItemsSource="{Binding Source={StaticResource familyCVS}, Path=., Mode=TwoWay}" 
        IsSynchronizedWithCurrentItem="True" 
        ItemTemplate="{StaticResource familyTemplate}" 
        SelectionChanged="familyList_SelectionChanged" />
    
  • Когда мне нужно добавить или удалить записи / объекты, я вручную делаю это как из модели данных сущности, так и из ObservableCollection:

    private void DeletePerson(Person person)
    {
        entities.DeleteObject(person);
        entities.SaveChanges();
        personOC.Remove(person);
    }
    
  • Я обычно использую элементы управления StackPanel и DockPanel для позиционирования элементов. Иногда я использую Grid, но это сложно поддерживать: если вы хотите добавить новую строку в верхнюю часть вашей сетки, вам нужно дотронуться до каждого элемента управления, непосредственно размещенного в сетке, чтобы сказать ей использовать новую строку. Uggh. (Microsoft никогда не получала концепцию СУХОЙ.)

  • Я почти никогда не использую конструктор VS WPF для добавления, изменения или позиционирования элементов управления. Дизайнер WPF, поставляемый с VS, довольно смутно помогает увидеть, как будет выглядеть ваша форма, но даже тогда, ну, не совсем, особенно если вы используете шаблоны данных, которые не привязываются к данным, которые доступны на время проектирования. Если мне нужно отредактировать свой XAML, я беру это как человек и делаю это вручную.

  • Большая часть моего реального кода на C #, а не XAML. Как я уже упоминал в другом месте , полностью за исключением того факта, что я еще не привык «думать» об этом, XAML кажется мне неуклюжим, уродливым языком, который также приходит с плохой поддержкой дизайнера и intellisense, и что не может быть отлажено. Uggh. Следовательно, всякий раз, когда я ясно вижу, как сделать что-то в коде C #, что я не могу легко увидеть, как это сделать в XAML, я делаю это в C #, без извинений. Было много написано о том, что это хорошая практика - почти никогда не использовать код позади на странице WPF (скажем, для обработки событий), но, по крайней мере, пока это не имеет для меня никакого смысла. Почему я должен делать что-то на уродливом, неуклюжем языке с ужасным синтаксисом, поразительно плохим редактором и практически без безопасности типов, когда я могу использовать хороший, чистый язык, такой как C #, с редактором мирового класса, почти идеальным intellisense, а беспрецедентный тип безопасности?

Так вот где я. Какие-либо предложения? Я что-то упускаю из этого? Что-нибудь, что я действительно должен думать о том, чтобы поступить иначе?

Принятый ответ

Вам нужно внедрить шаблон репозитория для отделения проблем WPF от EF

Затем вы можете использовать универсальные шаблоны, чтобы уменьшить сложность обработки EF для CollectionViewSource.

Хорошо спроектированный репозиторий должен снижать уровни кода и позволять заменять любой ORM (требуется для достойного тестирования)

Некоторые идеи для этого здесь

http://blog.nicktown.info/2008/12/10/using-a-collectionviewsource-to-display-a-sorted-entitycollection.aspx


Популярные ответы

Кроме того, я не думаю, что вам нужно делать ToList () здесь. Я считаю, что ObservableCollection () принимает IEnumerable, семейства которого уже есть. Если вы создадите ToList, а затем передадите его в ObservableCollection, то, я думаю, вы дважды переберите все свои записи.

familyOC = new ObservableCollection<Family>(families.ToList());

Вместо этого попробуйте это, что должно быть немного быстрее:

familyOC = new ObservableCollection<Family>(families);


Related

Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow