Books Authors Web 服务实现(EDM 示例应用程序)

本组主题中讨论的 Books Authors Web 服务示例从 Books Authors Web 服务架构(EDM 示例应用程序)主题中的架构实现实体数据模型 (EDM) 应用程序。

Books Authors Web 服务使用的命名空间和类是从使用概念架构定义语言 (CSDL) 设计的实体和关联生成的。存储类数据的数据库表由使用存储架构定义语言 (SSDL) 编写的元数据描述。设计架构中的类型映射到映射规范语言 (MSL) 中的存储元数据。

可编程对象模型取决于架构和映射规范。对象模型是从概念架构生成的;生成的 DLL 要求概念架构和存储架构以及映射规范处在要建立的实体连接的作用域中。

建立 EntityConnection 使代码可以使用类和数据源。有关生成类库的更多信息,请参见实现实体 (EDM)

Web 服务项目

使用本节所述 Books Authors 对象模型的 Web 服务是作为独立项目实现的。创建基于 ASP.NET Web 服务模板的项目。添加对 System.Data.Entity DLL 以及在 EDM 模型对象项目中创建的 BooksAuthors DLL 的引用。添加引用将创建包含 DLL 的 bin 文件夹。

架构必须在可执行文件的作用域中。将 BooksAuthors 类库项目中的架构添加到 Web 服务项目中的 App_Data 文件夹。

Web.config

在 BooksAuthors Web 服务中,需要 Web.config 文件才能定位 EDM 对象所用的架构、元数据和数据服务器。下面的 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注意

该连接字符串将多个活动结果集设置为 true,为了使每次在同一个连接上打开另一个数据读取器时都在关联上调用 Load 方法,必须进行这样的设置。

服务在 Web 服务器上运行时,必须从虚拟目录中查找架构的路径。一种实现方式是使用 global.asax 文件中的 Server.MapPath 方法。在下面的代码中,MapPath 方法查找完全限定绝对路径。MapPath 找到的路径被从 Web.config 文件中获取的连接字符串替换。

在下面紧接着演示的 global.asax 文件的 Application_Start 方法之后将演示这些过程。

  <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 服务构造函数中的代码。连接字符串存储在 Web.Config 文件中,因此,可以使用下面这行代码建立连接:BooksAuthors db = new BooksAuthors(Application.Contents["ConnString"] as String))。此 Web 服务分别使用该服务提供的每个方法初始化实体连接。SQL Server 使用连接池,因此这不会影响性能。

此应用程序中的 Web 服务方法实现为初始化并返回 List<T> 的公共方法。这些列表由 Web 服务的协议转换为文本并以 XML 数据的形式返回。

第一个方法返回该系统中的所有 Books 实体。为了检索 Books 数据,向 Web 服务打开了到 BooksAuthors 数据的连接。初始化 Books 类型的新 List<T>,并用它将 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();
        }
    }

下面的方法对书名使用参数化查询,以查找 BookTitle 属性与所提供书名相等的所有 BooksInfo 实体。通过使用这些 BooksInfo 实体,可以导航 Authors 实体和 BooksInfo 实体之间的关联,从而访问与给定书名关联的所有 Authors 实体。

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();
        }
    }

此 Web 服务还可以用于添加 Books 实体和所添加的书的作者。实体连接可用于写入数据和读取数据。下面的 Web 方法创建表示书及其作者的实体,将这些实体添加到 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();

        }
    }

本示例中最后一个方法返回包含书名、书 ID 号、作者姓氏和定位符信息的 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();
        }
    }

此方法用于在客户端应用程序中显示数据,如 Web 服务的客户端应用程序(EDM 示例应用程序) 中所示。

另请参见

概念

Books Authors Web 服务(EDM 示例应用程序)
Books Authors Web 服务架构(EDM 示例应用程序)
Web 服务的客户端应用程序(EDM 示例应用程序)

其他资源

EDM 规范
架构和映射规范(实体框架)