次の方法で共有


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 Model Object プロジェクトで作成した 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>

[!メモ]

この接続文字列は、複数のアクティブ結果セットを true に設定します。これは、別のデータ リーダーが同じ接続上で既に開いている場合にアソシエーションに対して Load メソッドを呼び出すために必要になります。

サービスを Web サーバーで実行する場合、スキーマへのパスを仮想ディレクトリから検索する必要があります。これを実行する方法の 1 つは、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 ファイルに格納されているため、1 行のコード (BooksAuthors db = new BooksAuthors(Application.Contents["ConnString"] as String)) で接続を確立できます。この Web サービスでは、サービスによって提供されるメソッドごとにエンティティ接続を個別に初期化します。SQL Server では接続プールが使用されるため、これによってパフォーマンスが低下することはありません。

このアプリケーションの Web サービス メソッドは、List<T> を初期化して返すパブリック メソッドとして実装されます。リストは Web サービスのプロトコルによってテキストに変換され、XML データとして返されます。

最初のメソッドは、システム内のすべての Books エンティティを返します。Books データを取得するために、BooksAuthors データへの接続が Web サービスに対して開かれます。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 仕様
スキーマおよびマッピング スキーマ (Entity Framework)