書籍作者 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>
附註 |
---|
此連接字串會將 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 範例應用程式)