書籍作者 Web 服務實作 (EDM 範例應用程式)

這一組主題內所討論的書籍作者 Web 服務範例會從書籍作者 Web 服務結構描述 (EDM 範例應用程式)主題內的結構描述實作 實體資料模型 (EDM) 應用程式。

此書籍作者 Web 服務使用的命名空間和類別是從概念結構定義語言 (CSDL) 中設計的實體和關聯建置而來。儲存類別之資料的資料庫資料表是由存放結構定義語言 (SSDL) 撰寫的中繼資料所描述。設計結構描述中的型別會對應到對應規格語言 (MSL) 中的儲存中繼資料。

可程式化物件模型取決於結構描述和對應規格。物件模型是從概念結構描述建置而來;產生的 DLL 需要概念結構描述和儲存結構描述,而且對應規格必須在範圍內,才能建立實體連接。

建立 EntityConnection 可供程式碼使用類別和資料來源。如需建置類別庫 (Class Library) 的詳細資訊,請參閱實作實體 (EDM)

Web 服務專案

本章節描述之使用書籍作者物件模型的 Web 服務會實作為個別的專案。建立以 ASP.NET Web 服務範本為根據的專案。加入 EDM 模型物件專案內建立之 System.Data.Entity DLL 的參考及 BooksAuthors DLL 的參考。加入參考會建立包含 DLL 的 bin 資料夾。

結構描述必須在可執行檔的範圍內。將 BooksAuthors 類別庫專案中的結構描述加入到 Web 服務專案內的 App_Data 資料夾。

Web.config

需要 Web.config 檔才能尋找結構描述、中繼資料及 BooksAuthors Web 服務中的 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附註

此連接字串會將 Multiple Active Result Set (MARS) 設定為 true,因為當相同連接上已經開啟另一個資料讀取器時,會需要這樣的設定來叫用關聯上的 Load 方法。

在 Web 伺服器上執行此服務時,它必須從虛擬目錄尋找結構描述的路徑。讓這項處理有效的一個方式是使用 global.asax 檔中的 Server.MapPath 方法。在下列程式碼中,MapPath 方法會尋找完整的絕對路徑。取自 Web.config 檔的連接字串中會替代 MapPath 找到的路徑。

程序示範在底下顯示之 global.asax 檔中的 Application_Start 方法之後。

  <script >

    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 會使用連接共用 (Connection Pooling),好讓它不會妨礙效能。

此應用程式中的 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();

        }
    }

此範例的最後一個方法會傳回包含書名、書籍識別碼、作者姓氏和定位器資訊的 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 範例應用程式) 中所示。

另請參閱

概念

書籍作者 Web 服務 (EDM 範例應用程式)
書籍作者 Web 服務結構描述 (EDM 範例應用程式)
Web 服務的用戶端應用程式 (EDM 範例應用程式)

其他資源

EDM 規格
結構描述和對應規格 (Entity Framework)