четверг, 23 июня 2011 г.

MVC - часть2. Data Access Level


В прошлой статье мы сошлись на том, что получать данные в контроллере не  есть хорошо и правильно. И это так. С данными должна работать модель. Но обычно программисты выделяют еще один уровень, еще одну модель, которую будет использовать основная, - Data Access Level. То есть модель, которая непосредственно получает данные из БД, XML и других источников. И тут мы подходим к вопросу о технологии доступа к данным. Т.к. мы программируем в мире объектно-ориентированном, то и логичным было появление так называемых объектно-ориентированных технологий доступа к данным - object-relational mapping (ORM). Что это, какие виды и типы бывают, мы рассматривать не будем – оставляю это для самостоятельного изучения. В нашем же проекте мы будем использовать технологию ADO.NET Entity Framework (EF), являющейся ORM решением для .Net Framework от Microsoft.
Напомню, что у нас есть таблица в БД MS SQL Server с данными об объектах нашей карты (листинг 1).
Листинг 1 – Таблица объектов карты
CREATE TABLE [dbo].[Map] (
  [id] int IDENTITY(1, 1) NOT NULL,
  [ObjectName] nvarchar(128) COLLATE Cyrillic_General_CI_AS NULL,
  [ObjectAddress] nvarchar(256) COLLATE Cyrillic_General_CI_AS NULL,
  [Longitude] nvarchar(128) COLLATE Cyrillic_General_CI_AS NULL,
  [Latitude] nvarchar(128) COLLATE Cyrillic_General_CI_AS NULL,
  PRIMARY KEY CLUSTERED ([id])
)

Создадим Data Entity модель по этой таблице. Для это щелкаем правой кнопкой на папке Model нашего проекта, выбираем там AddNew Item, видим диалоговое окно как на рисунке 1.

                            Рисунок 1 – Добавление нового элемента в проект

В этом диалоге выбираем раздел Data – ADO.NET Entity Data Model, называем нашу модель (например, MapDataModel). Далее студия запускает визард, который помогает нам правильно сформировать модель. Идем по порядку: Choose Model Contents – Generate from database, Choose Your Data Connection – вносите настройки коннекта к вашей БД, Choose Your Database Objects – Tables (Map). Все, готово! Через пару секунд студия сгенерирует нам модель доступа к данным (рисунок 2).
Рисунок 2 – Модель данных

У нас данные хранятся крайне просто. Если не сказать примитивно. Если же данные образуют сложную систему с внешними ключами и прочим, то студия это все поймет и сгенерирует соответствующее количество классов с соответствующими связями. Если мы заглянем в файл MapDataModel.Designer.cs, то увидим содержимое рисунка 3.
Рисунок 3 – Классы, описывающие данные

Теперь как с этим работать. Давайте создадим модель DataManager (Model – Add –Class - DataManager). Создадим конструктор (листинг 2).
Листинг 2Конструктор DataManager
        private ProjectEntities _db;

        public DataManager()
        {
            _db = new ProjectEntities();
        }

Тут все понятно – мы создаем соединение к нашей БД, чтоб через него брать данные. Далее нам нужно сформировать лист, который будет отдаваться клиенту (листинг 3).
Листинг 3 – Формирование списка объектов для карты
        public List<object> GetListObjectMap()
        {
            List<object> list = new List<object>();

            foreach (Map item in _db.Map)
            {
                var data = new
                {
                    Name = item.ObjectName,
                    Latitude = item.Latitude,   //широта
                    Longitude = item.Longitude, //долгота
                    Html = item.ObjectAddress,
                };
                list.Add(data);
            }
            return list;
        }

Тут тоже понятно – каждую запись из таблицы БД в цикле мы добавляем в список.
Теперь идем в контроллер и очищаем метод ObjectToMap(). Создадим в нем экземпляр нашего DataManager и сформированный лист отдадим клиенту (листинг 4).
Листинг 4 – Обновленный метод контроллера ObjectToMap()
        [AcceptVerbs(HttpVerbs.Get)]
        public JsonResult ObjectToMap()
        {
            DataManager dm = new DataManager();

            return Json(dm.GetListObjectMap(), JsonRequestBehavior.AllowGet);
        }

Рисунок 4 – Результат работы

Просто? Вот так красиво и удобно.
Для лучшего понимания того, как и что делать, рекомендую изучать видеоподкасты на сайте . В них с комментариями описываются основные приемы работы от самых простых к сложным.
В следующей статье мы рассмотрим, как можно редактировать объекты нашей карты.

11 комментариев:

Сергей комментирует...

Здравствуйте.
Спасибо за публикации. Они для меня, новичка, оказались очень полезными. Очень жду следующей части!
Сергей.

dedMazDie комментирует...

Спасибо за отзыв!
На самом деле, это очень-очень примитивный уровень. И эти статьи сильно критикуют мегаГуру. Поэтому мне довольно сложно противодействовать этому. Но раз есть отзывы, что кому то есть от этого польза, то, конечно, я буду стараться описывать свои мытарства по освоению технологий :)

Сергей комментирует...

Эти статьи не для мегаГуру, а для тех кто только вживается в технологию. Например я геодезист и картограф. И мне примитивный уровень самый доступный. Рад что продолжаете писать!

Сергей комментирует...

Может знаете как выносить метки на гугловской карте?
На карте Яндекса руководствуясь Вашим описанием сделал следующее http://landmap.info/Map/MapYandex

dedMazDie комментирует...

Спасибо за отзыв! Буду стараться писать :)

Я не совсем понял, что значит выносить метки? На Вашем сайте я увидел, что балуны на карте Гугла не пропадают после вызова другой метки. Это имеете в виду?

Сергей комментирует...

Я написал комментарий, а потом сел делать. И ура! Получилось! А имел в виду сами значки, которые уже стоят.

Сергей комментирует...

Здравствуйте. У меня вопрос. Почему на яндекс карте балуны такие кривые получаются? Стили шаблона проекта так влияют?

dedMazDie комментирует...

Да, я думаю, дело в стилях.

Кстати в варианте от Гугла на вашем сайте после открытия нового балуна старый не исчезает. Смотреть неудобно. Это в опере так. В других брагаузерах не смотрел :)

Сергей комментирует...

Это везде так. Пока не стал разбираться в причинах. Вообще хотел использовать свою карту с компонентом AspMap, но не могу разобраться как с ним работать в MVC.

Сергей комментирует...

Если интересно:
У балуна появились отступы, растянулся во всю ширину карты, съехала тень и др.
Это проблема верстки. CSS-стили на вашем сайте перекрывают стили API Яндекс.Карт. Воспользуйтесь DOM-инспектором (например, для браузера Firefox - Firebug) и исправьте ошибку. Чаще всего подобные конфликты вызываются стилями, установленными для элементов table, tr, td. В этом случае задайте уточняющее правило, заменив общее правило на более частное. Например, правило


td {padding: 5px}можно заменить наtd.myClass {padding: 5px}

Но пка у себя не изменил table ничего не получалось.

dedMazDie комментирует...

Это пример для изучения. Тут не преследовалось цели сделать все красивости. А так то да - в балуне все задается через таблицу. И если в CSS задать свойства таблицы без указания конкретного класса, то съедет и таблица в балуне.