Поделиться через


Реализация веб-службы Books Authors Web Service (образец приложения модели EDM)

Пример веб-службы Books Authors Web Service, обсуждаемый в этой группе разделов, реализует приложение модели Entity Data Model (EDM) по схемам из раздела Схемы веб-службы Books Authors (образец приложения модели EDM).

Пространство имен и классы, используемые веб-службой Books Authors Web Service, строятся на основе сущностей и ассоциаций, созданных на языке CSDL. Таблицы базы данных, где хранятся данные этих классов, описываются метаданными, которые написаны на языке SSDL. Типы схемы сопоставлены с метаданными хранилища с помощью языка MSL.

Программируемая модель объектов зависит как от схем, так и от спецификации сопоставления. Модель объектов строится на основе концептуальной схемы; итоговая динамическая библиотека требует, чтобы концептуальные схемы, схемы хранения и спецификация сопоставления находились в области действия, иначе не удастся установить соединение сущности.

Установление соединения EntityConnection делает классы и источник данных доступными для программного кода. Дополнительные сведения о построении библиотеки классов см. в разделе Реализация сущностей (модель EDM).

Проект веб-службы

Веб-служба, использующая модель объектов Books Authors Web Service, описанную в этом разделе, реализована как отдельный проект. Создайте проект на основе шаблона веб-службы ASP.NET. Добавьте ссылки на динамическую библиотеку System.Data.Entity и динамическую библиотеку BooksAuthors, созданную в проекте EDM Model Object. В результате добавления ссылок создается папка bin, в которой расположены файлы DLL.

Схемы должны находиться в области исполняемых файлов. Добавьте схемы из проекта библиотеки классов BooksAuthors в папку App_Data проекта веб-службы.

Файл Web.config

Файл Web.config нужен для поиска схем, метаданных и сервера данных, используемых объектами модели EDM веб-службы BooksAuthors Web Service. В приведенном ниже фрагменте на языке XML показан файл Web.config для этой службы. В строке соединения указаны сервер и база данных, используемые спецификацией сопоставления для установления соединения между программируемыми классами и базой данных.

<?xml version="1.0"?>
<configuration>

    <configSections/>

    <system.web>
        <authentication mode="Windows"/>
        <identity impersonate ="true"/>
    </system.web>

    <connectionStrings>
        <add name="BooksAuthorsEntities"
         connectionString=
         "metadata=C:\Inetpub\wwwroot\BooksAuthorsWebSrv\App_Data\;
         provider=System.Data.SqlClient; 
         provider connection string='server=serverName; 
         database=BooksAuthors; 
         integrated security=true;
         multipleactiveresultsets=true'" 
         providerName="System.Data.EntityClient"/>
    </connectionStrings>
</configuration>
NoteПримечание.

Эта строка соединения устанавливает для параметра режима MARS значение True, когда это требуется для вызова метода Load для ассоциаций, если на данном соединении уже открыт другой модуль чтения данных.

При работе службы на веб-сервере ей нужно находить путь к схемам из виртуального каталога. Этого можно добиться, например, использованием метода Server.MapPath, описанного в файле global.asax. В приведенном далее программном коде метод MapPath находит полностью заданный абсолютный путь. Путь, обнаруженный методом MapPath, подставляется в строку соединения, полученную из файла Web.config.

Эти процедуры располагаются после метода Application_Start в файле global.asax, приведенном ниже.

  <script runat="server">

    void Application_Start(object sender, EventArgs e) 
    {
        String connString = 
          System.Web.Configuration.WebConfigurationManager.
          ConnectionStrings["BooksAuthorsEntities"].ConnectionString;

        connString = connString.Replace(@"C:\Inetpub\wwwroot\BooksAuthorsWebSrv\App_Data\",
         Server.MapPath("~/App_Data"));

        Application.Contents.Add("ConnString", connString);

    }

  </script>

В декларациях Web Method измененная строка соединения считывается из коллекции Application.Contents и используется для создания экземпляра контекста объекта следующим образом: BooksAuthorsEntities db = new BooksAuthorsEntities(Application.Contents["ConnString"] as String).

Код приложения

Установление соединения сущности зависит от строки соединения в файле Web.config и программного кода конструктора веб-службы. Строка соединения хранится в файле Web.Config. Поэтому соединение можно установить одной строкой кода: BooksAuthors db = new BooksAuthors(Application.Contents["ConnString"] as String)). Эта веб-служба инициализирует соединение сущности отдельно в каждом методе, предоставляемом службой. Сервер SQL Server использует пул соединений, поэтому производительность не страдает.

Методы веб-службы в данном приложении реализованы как открытые методы, инициализирующие и возвращающие объект-список List<T>. Списки преобразуются в текст протоколами веб-служб и возвращаются в виде XML-данных.

Первый метод возвращает все сущности Books, существующие в системе. Для получения данных по объектам Books веб-служба устанавливает соединение с данными BooksAuthors. Инициализируется новый объект-список List<T> типа Books, который затем используется для преобразования запроса Books Query<T> в массив, который может быть возвращен в точку вызова запроса. Затем соединение закрывается.

    [WebMethod]
    public Books[] GetBooks()
    {
        using (BooksAuthorsEntities db =
            new BooksAuthorsEntities(
                Application.Contents["ConnString"] as String))
        {
            List<Books> bookList = new List<Books>(db.Books);
            return bookList.ToArray();
        }
    }

Следующий метод работает так же и возвращает сущности Authors.

    [WebMethod]
    public Authors[] GetAuthors()
    {
        using (BooksAuthorsEntities db =
            new BooksAuthorsEntities(
                Application.Contents["ConnString"] as String)) 
        {
            List<Authors> authorsList = new List<Authors>(db.Authors);
            return authorsList.ToArray();
        }
    }

Показанный ниже метод использует параметризованный запрос по заголовку книги, чтобы найти все сущности BooksInfo, у которых значение свойства BookTitle совпадает с указанным заголовком. Через сущности BooksInfo можно пройти по ассоциациям сущностей Authors с сущностями BooksInfoAuthors, чтобы перебрать все сущности авторов, которые связаны с книгой с указанным заголовком.

Массив значений типа Authors возвращается в точку вызова метода.

    [WebMethod]
    public Authors[] GetAuthorsFromBookTitle(string bookTitle)
    {
        using (BooksAuthorsEntities db =
            new BooksAuthorsEntities(
                Application.Contents["ConnString"] as String))
        {
            ObjectParameter param = new ObjectParameter("p", bookTitle);

            List<Authors> authorsList = new List<Authors>();

            foreach (BooksInfo bksInfo in db.BooksInfo.Where(
                "it.BookTitle = @p", param))
            {
                bksInfo.AuthorsReference.Load();
                authorsList.Add(bksInfo.Authors);

            }
            return authorsList.ToArray();
        }
    }

Метод GetBooksFromAuthorLastName работает так же, как и предыдущий, и возвращает массив книг на основе запроса по фамилии автора.

    [WebMethod]
    public Books[] GetBooksFromAuthorLastName(string authorLastName)
    {
        using (BooksAuthorsEntities db =
            new BooksAuthorsEntities(
                Application.Contents["ConnString"] as String))
        {
            ObjectParameter param = new ObjectParameter("p", authorLastName);

            List<Books> booksList = new List<Books>();

            foreach (BooksInfo bksInfo in db.BooksInfo.Where(
                "it.AuthorLastName = @p", param))
            {
                bksInfo.BooksReference.Load();
                booksList.Add(bksInfo.Books);
            }
            return booksList.ToArray();
        }
    }

Эту веб-службу можно также использовать для добавления сущностей Books, а также автора или авторов добавляемых книг. Соединение сущности может использоваться для записи и чтения данных. Следующий веб-метод создает сущности, представляющие книгу и ее автора, добавляет сущности в контекст объекта ObjectContext и вносит изменения в базу данных. Этот метод можно вызывать столько раз, сколько необходимо, чтобы добавить нескольких авторов для одного и того же названия.

    [WebMethod]
    public void AddBook(string title, string authorFirstName,
        string authorLastName, string infoUri, string isbnNumber)
    {
        using (BooksAuthorsEntities db =
            new BooksAuthorsEntities(
                Application.Contents["ConnString"] as String))
        {

            BooksInfo newBooksInfo = new BooksInfo();
            newBooksInfo.BookInfoId = Guid.NewGuid();
            newBooksInfo.AuthorLastName = authorLastName;
            newBooksInfo.BookTitle = title;
            if (!infoUri.Equals(""))
                newBooksInfo.InfoLocator = infoUri;

            Books existingBook = null;
            ObjectParameter param = new ObjectParameter("p", title);
            ObjectQuery<Books> queryBook = db.Books.Where(
                "it.Title = @p", param);

            if (queryBook.Exists())
            {
                existingBook = db.Books.Where(
                    "it.Title = @p", param).First();
                newBooksInfo.Books = existingBook;
            }
            else
            {
                Books newBook = new Books();
                newBook.BookId = isbnNumber;
                newBook.Title = title;
                newBooksInfo.Books = newBook;
                db.AddToBooks(newBook);
            }

            Authors existingAuthor = null;
            ObjectParameter aParam = new ObjectParameter(
                "p", authorLastName);
            ObjectParameter aParam2 = new ObjectParameter(
                "q", authorFirstName);
            ObjectParameter[] pars =
                new ObjectParameter[] { aParam, aParam2 };
            ObjectQuery<Authors> queryAuthor = db.Authors.Where(
                "it.LastName = @p AND it.FirstName = @q", pars);

            if (queryAuthor.Exists())
            {
                existingAuthor = db.Authors.Where(
                    "it.LastName = @p AND it.FirstName = @q",
                    pars).First();
                newBooksInfo.Authors = existingAuthor;
            }
            else
            {
                Authors newAuthor = new Authors();
                newAuthor.AuthorId = Guid.NewGuid();
                newAuthor.LastName = authorLastName;
                newAuthor.FirstName = authorFirstName;
                newBooksInfo.Authors = newAuthor;
                db.AddToAuthors(newAuthor);
            }

            db.AddToBooksInfo(newBooksInfo);
            db.SaveChanges();

        }
    }

Последний метод данного примера возвращает сущности BooksInfo, содержащие название книги, ее идентификационный номер, фамилию автора и информацию о местонахождении.

    [WebMethod]
    public BooksInfo[] GetBooksInfo()
    {
        using (BooksAuthorsEntities db =
            new BooksAuthorsEntities(
                Application.Contents["ConnString"] as String))
        {
            List<BooksInfo> booksInfoList =
                new List<BooksInfo>(db.BooksInfo);

            return booksInfoList.ToArray();
        }
    }

Этот метод используется для вывода данных в клиентских приложениях, показанных в разделе Клиентское приложение для веб-службы (образец приложения модели EDM).

См. также

Основные понятия

Веб-служба Books Authors (образец приложения модели EDM)
Схемы веб-службы Books Authors (образец приложения модели EDM)
Клиентское приложение для веб-службы (образец приложения модели EDM)

Другие ресурсы

Спецификации модели EDM
Спецификация схем и сопоставлений (платформа Entity Framework)