Рекомендации по использованию 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 для размещения элементов. Иногда я использую сетку, но ее трудно поддерживать: если вы хотите добавить новую строку в верхнюю часть своей сетки, вам нужно коснуться каждого элемента управления, непосредственно размещенного в сетке, чтобы сказать ему использовать новую строку. Угу. (Microsoft, похоже, никогда не получала сухую концепцию.)
я почти никогда не использую VS WPF designer для добавления, изменения или позиционирования элементов управления. Конструктор WPF, который поставляется с VS, немного помогает увидеть, как будет выглядеть ваша форма, но даже тогда, ну, не совсем, особенно если вы используете шаблоны данных, которые не привязаны к данным, доступным во время разработки. Если мне нужно отредактировать мой XAML, я беру его как человек и делаю это вручную.
большая часть моего реального кода находится в C#, а не XAML. Как я уже говорил в другом месте, совершенно помимо того, что я еще не привык "думать" в нем, XAML поражает меня как неуклюжий, уродливый язык, который также поставляется с плохой поддержкой дизайнера и intellisense, и это не может быть отлажено. Угу. Следовательно, всякий раз, когда я могу ясно видеть, как сделать что-то в коде C#, что я не могу легко увидеть, как это сделать в XAML, я делаю это в C#, без извинений. Там было много написано о том, как это хорошая практика, чтобы почти никогда не использовать код за пределами страницы WPF (скажем, для event-handling), но до сих пор, по крайней мере, это не имеет для меня никакого смысла. Почему я должен делать что-то на уродливом, неуклюжем языке с ужасным синтаксисом, удивительно плохим редактором и практически без безопасности типов, когда я могу использовать хороший, чистый язык, такой как C#, который имеет редактор мирового класса, почти идеальный intellisense и беспрецедентную безопасность типов?
так вот где я нахожусь. Есть предложения? Я пропустил какие-то большие части этого? Все, что я действительно должен думать делать по-другому?
6 ответов:
вам нужно реализовать шаблон репозитория, чтобы отделить проблемы WPF от EF
затем вы можете использовать универсальные средства для уменьшения сложности EF для обработки CollectionViewSource
хорошо спроектированный репозиторий должен уменьшить уровни кода и позволить заменить любой ORM (необходимый для достойного тестирования)
некоторые идеи для этого здесь
кроме того, я не думаю, что вам нужно сделать ToList() здесь. Я считаю, что ObservableCollection () принимает IEnumerable, который уже является семейством. Если вы сделаете Толист, а затем передадите его в ObservableCollection, то я думаю, что вы дважды пройдете через все свои записи.
familyOC = new ObservableCollection<Family>(families.ToList());
вместо этого попробуйте это, что должно быть немного быстрее:
familyOC = new ObservableCollection<Family>(families);
Я понимаю, откуда вы пришли. Это статья Джоша Смита помог мне изменить (или начать менять) мышление, чтобы вы могли извлечь некоторую пользу из WPF, а не видеть его как странную, обструктивную, трудно отлаживаемую и недружественную структуру!
мои рекомендации, если возможно, используйте Expression Blend для разработки вашего интерфейса, вместо кода позади и вместо использования конструктора Visual Studio, это сэкономит вам много времени. Также попробуйте переосмыслить использование C# вместо xaml. Xaml не так уродлив, если вы делаете это "способом WPF". Часто, когда я думаю, что проще использовать код вместо xaml, это потому, что я делаю это неправильно и нужно переосмыслить, как лучше всего работать с WPF/xaml. Xaml-это здорово как только вы привыкнете к нему. Я также использовал Entity framework, который еще не слишком велик. Я предпочитаю NHibernate.
Я пошел по этой ссылке из моего блога и хотел бы упомянуть что-то еще, что я нашел с EF. Немного не по теме,но не совсем.
Я заметил некоторые сумасшедшие проблемы с производительностью с EF при использовании .Включать. MS объясняет, почему в статье на их веб-сайте я фактически начал переносить большую часть своего кода для использования .Вместо этого загрузите метод.
потому что это утомительно и потому что я не мог найти другой способ сделать это... Я создал свой собственный метод называется "IncludeByRoundTrip". То, что он делает, принимает путь объекта и гарантирует, что весь путь загружен. Конечный результат такой же, как при использовании include однако за кулисами, я просто вызываю Load на все свойства в графе объектов.
Это было бы похоже на выполнение чего-то вроде заказа.Нагрузка ("Клиент.Адрес"), если такой механизм существует. В любом случае, проверьте это в моем блоге и дайте мне знать ваши выводы. Мне было бы любопытно узнать, заметили ли другие замедления с помощью Включите и если у вас есть другие подходы при атаке ситуации.
есть больше информации о моем решении на: http://blog.nicktown.info/2009/07/27/method-to-load-an-entire-object-graph-using-adonet-entity-framework.aspx.
опять же, извините, что это было немного не по теме, но я с нетерпением жду ваших ответов.
другой инструмент может быть BindableLINQ
Bindable LINQ-это набор расширений для LINQ, которые добавляют привязку данных и изменяют возможности распространения стандартных запросов LINQ