16 December 2008

ADO.NET Entity Framework близкое юзание

.NET
Тем, кто пишет запросы в коде страницы посвящается...

Приветствую всех!

На хабре есть немного информации о том, что в следующей версии VisualStudio 2008 будет ADO.NET EntityFramework. (Открою секрет, эта версия уже появилась.) Эта разработка представляет собой универсальный фреймворк, который позволяет создавать даталогику вашего проекта в пару кликов мыши.
До сих пор, работая с даталогикой, я сталкивался с 2 видами проектов. Первые были созданы на небезызвестном фреймворке NHibernate, другие реализовывали даталогику программистами. Я уже 3 года занимаюсь написанием и разработкой различных систем и всё это время разрабатывал логику работы с данными исключительно ручками.
И вот, на днях, после того, как я поставил новую винду, я скачал VisualStudio WebDeveloper Express, и с радостью обнаружил в комплекте поставки ADO.NET EntityFramework. Через некоторое время зарегистрировал домен, создал простенький сайт, и начал тренировать свои силы в написании программ под этот фреймворк.


Я был немного неприятно удивлён тем, что большинство статей о ADO.NET EF были узконаправленными. Невозможно было найти полной информации, от начала до конца, о том, как правильно настроить базу, создать сущности и произвести базовые действия над этими сущностями. Большинство статей раскрывают лишь одну из этих тем. Что-же, обучаясь, я решил поделиться опытом с тобой %username%. В то же время, используя мой код вы не сможете поднять систему работы с бизнес-процессами, но всё-таки, вы поймёте с какой стороны к чему подходить.



Для начала необходимо создать простой Web проект с базой данных. К базе данных тоже неплохо было бы подключится сразу через DataBase Explorer. Просто потом будет удобнее.



После этого, в проект надо добавить новый элемент «ADO.NET Entity Data Model».



Системе надо будет указать строку для соединения с базой, а так же указать, откуда возьмётся первая модель ADO.NET EF.



В своей БД я уже имею две очень простых таблицы Post и User, поэтому не мудрствуя лукаво, я заставил систему создать модель на основе моей БД. После всех этих, очень простых действий, я получил рабочую модель БД. Более того, изучив эту модель визуально, я не забыл заглянуть в код, и посмотреть, как же фрейворк описывает все мои классы?

  1. namespace DataBaseCore
  2. {
  3. /// <summary>
  4. /// There are no comments for DbModel in the schema.
  5. /// </summary>
  6. public partial class DbModel : global::System.Data.Objects.ObjectContext
  7. {
  8. /// <summary>
  9. /// Initializes a new DbModel object using the connection string found in the 'DbModel' section of the application configuration file.
  10. /// </summary>
  11. public DbModel() :
  12. base("name=DbModel", "DbModel")
  13. {
  14. this.OnContextCreated();
  15. }
  16. /* Урезал за ненадобностью */
  17. [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="DataBaseCore", Name="Post")]
  18. [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
  19. [global::System.Serializable()]
  20. public partial class Post : global::System.Data.Objects.DataClasses.EntityObject
  21. {
  22. /// <summary>
  23. /// Create a new Post object.
  24. /// </summary>
  25. /// <param name="id">Initial value of Id.</param>
  26. public static Post CreatePost(int id)
  27. {
  28. Post post = new Post();
  29. post.Id = id;
  30. return post;
  31. }
* This source code was highlighted with Source Code Highlighter.


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

Ну, что же, код у нас уже есть, осталось только его начать использовать. И тут, нам открываются все прелести и возможности ASP.NET. Среди немалого количества источников данных на странице я увидел Entity Data Source, который с удовольствием предоставляет данные по запросу из нашего класса. Перетаскиваем его на форму, запускаем мастер настройки, и быстренько цепляем датасорс на нашу таблицу постов.



Несомненно, намного приятнее стало выглядеть описание датасорца в ASPX коде.
  1. <asp:EntityDataSource ID="dsPosts" runat="server" ConnectionString="name=DbModel"
  2. DefaultContainerName="DbModel" EntitySetName="Post">
  3. </asp:EntityDataSource>
* This source code was highlighted with Source Code Highlighter.

Можно сказать — блещет изяществом.

После появления на форме провайдера данных, нужен и потребитель. Не умничая, я добавил простенький код, который просто отображает все посты последовательно.

  1. <asp:Repeater runat="server" ID="repPosts" DataSourceID="dsPosts">
  2. <HeaderTemplate>
  3. </HeaderTemplate>
  4. <ItemTemplate>
  5. <div>
  6. <h3>
  7. <asp:Label ID="lblHeader" runat="server" Text='<%# Eval("Header") %>'></asp:Label>
  8. </h3>
  9. <p>
  10. <asp:Label ID="lblText" runat="server" Text='<%# Helpers.TypographText(Eval("Text").ToString()) %>'></asp:Label>
  11. </p>
  12. </div>
  13. </ItemTemplate>
  14. </asp:Repeater>
* This source code was highlighted with Source Code Highlighter.


И вот тут заканчивается самая простая часть моего повествования. До сих пор, всё что было сделано, можно повторить при помощи мыши. Это было достаточно просто. Мы только что создали объектно-ориентированное представления БД, и используя это представление, начали выводить данные из базы на страницу. При этом, мы ни разу не написали ни одного запроса, не получали данные из базы напрямую, etc…

Но, что же выводить пользователю, если у нас нет ничего в БД? Нехорошо. Надо написать форму заполнения базы. Теперь мы бросим мышепрограммирование, и займёмся написанием кода.

Я сделал два самых базовых действия для работы с постами в системе — это добавление и удаление. Сделать редактирование по аналогии с этим кодом не составит труда ни для кого.

  1. namespace DBW
  2. {
  3. public class Post
  4. {
  5. public Post()
  6. {
  7. }
  8. public static void New(String PostText, String PostHeader, Int32 UserId)
  9. {
  10. DataBaseCore.DbModel m = new DataBaseCore.DbModel();
  11. DataBaseCore.Post p = new DataBaseCore.Post();
  12. p.Header = PostHeader;
  13. p.Text = Helpers.TypographText(PostText);
  14. p.PublishDate = DateTime.Now;
  15. p.User = (from usr in m.User where usr.Id == UserId select usr).First();
  16. m.AddToPost(p);
  17. m.SaveChanges();
  18. }
  19. public static void Delete(Int32 PostId)
  20. {
  21. DataBaseCore.DbModel m = new DataBaseCore.DbModel();
  22. DataBaseCore.Post p = new DataBaseCore.Post();
  23. p = (from pst in m.Post where pst.Id == PostId select pst).First();
  24. m.DeleteObject(p);
  25. m.SaveChanges();
  26. }
  27. }
  28. }
* This source code was highlighted with Source Code Highlighter.


Казалось бы, всё просто, и да, это так. Но есть пара нюансов.
Во-первых — это LINQ. Без него в ADO.NET никуда. Так что не стоит отлынивать и вообще забивать на SQL или LINQ, писать запросы всё равно придётся.
Во-вторых — этот код автоматически генерируется фреймворком, поэтому особого удобства в некоторых моментах ожидать не придётся, и всегда надо быть готовым изменить уже созданный студией код. Например, тут в строке 16 было бы удобнее использовать не объект типа пользователь, который мне пришлось выбирать из БД, а сразу передавать значение идентификатора пользователя. Так было бы удобнее для этого кода, но это не универсально. Поэтому код нуждается в доработке и переосмыслении. Возможно просто надо передавать не идентификатор пользователя, а объект типа пользователь.

Что дальше? Дальше я буду продолжать писать проект, углубляясь в дебри ADO.NET Entity Framework, и буду с удовольствием делиться своими изысканиями с вами, уважаемые хабраюзеры. Соответственно, будут новые статьи, с более серьёзными и глубокими данными.

UPD. Тема очень обширная. Здесь не раскрыто и процента возможностей, но продолжение будет 8-)

Tags:ado.netasp.netentity frameworkпрограммирование
Hubs: .NET
+40
19.3k 40
Comments 120