Windows アプリで Entity Framework(以降 EF)を利用した Web API 経由で DB にアクセスする場合、マイクロソフトのエバンジェリストである鈴木章太郎さんの下記のブログ記事にすでに実装方法が紹介されています
ビジネス Windows ストアアプリ開発とアーキテクチャー Part 2: REST サービスの実装
ただ、改めていろいろ試したところ、別のやり方でも EF 経由の Web API を実装できました
まずは EF6 のコードファーストによるエンティティ作成
Entity Framework のモデル用に T4 テンプレートを作る - しっぽを追いかけて の投稿で紹介した T4 テンプレートで Portable Class Library のエンティティを自動生成します
<#@ template debug="true" hostspecific="false" language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".generated.cs" #> //<auto-generated> #region License //----------------------------------------------------------------------- // <copyright> // Copyright matatabi-ux 2014. // </copyright> //----------------------------------------------------------------------- #endregion namespace CatApp.Models { using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml.Serialization; using Newtonsoft.Json; <# Generate("Cat", new Property[] { new Property("id", "int", "ID", "[XmlAttribute(\"id\")]", "[JsonProperty(\"id\")]"), new Property("name", "string", "名称", "[XmlAttribute(\"name\")]", "[JsonProperty(\"name\")]"), new Property("image", "string", "画像パス", "[XmlAttribute(\"image\")]", "[JsonProperty(\"image\")]"), new Property("description", "string", "説明", "[XmlAttribute(\"description\")]", "[JsonProperty(\"description\")]"), }, new NavigationProperty[] { }, "猫情報", "[XmlRoot(\"cat\")]"); #> <#@ include file="../Templates/Entity.ttinclude" #> }
次に ASP.NET Web アプリケーションの Web API のプロジェクトを追加して、EF6 と JSON.Net のライブラリを NuGet でインストール、エンティティのある Portable Class Library をプロジェクト参照します
そのあと、DbContext を継承したコンテキストクラスを Web API プロジェクトの Model フォルダあたりに追加します
public class CatContext : DbContext { public CatContext() : base("Data Source=(localdb)\\v11.0;Initial Catalog=D:\\02_USERS\\DOCUMENTS\\CAT-DB.MDF;Integrated Security=True") { } public DbSet<Cat> Cats { get; set; } }
基底クラスのコンストラクタ引数は SQL Server ファイルの接続先文字列です
あとは Web API プロジェクトの Controllers フォルダ配下で右クリックメニューの [追加]-[コントローラー] を選び、次のような感じでポンポンと必要事項を選択して追加ボタンを押下すると・・・
Web API の REST サービスが自動生成されました!
簡単ですね!
public class CatsController : ApiController { private CatContext db = new CatContext(); // GET: api/Cats public IQueryable<Cat> GetCats() { return db.Cats; } // GET: api/Cats/5 [ResponseType(typeof(Cat))] public IHttpActionResult GetCat(int id) { Cat cat = db.Cats.Find(id); if (cat == null) { return NotFound(); } return Ok(cat); } // PUT: api/Cats/5 [ResponseType(typeof(void))] public IHttpActionResult PutCat(int id, Cat cat) { if (!ModelState.IsValid) { return BadRequest(ModelState); } if (id != cat.Id) { return BadRequest(); } db.Entry(cat).State = EntityState.Modified; try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { if (!CatExists(id)) { return NotFound(); } else { throw; } } return StatusCode(HttpStatusCode.NoContent); } // POST: api/Cats [ResponseType(typeof(Cat))] public IHttpActionResult PostCat(Cat cat) { if (!ModelState.IsValid) { return BadRequest(ModelState); } db.Cats.Add(cat); db.SaveChanges(); return CreatedAtRoute("DefaultApi", new { id = cat.Id }, cat); } // DELETE: api/Cats/5 [ResponseType(typeof(Cat))] public IHttpActionResult DeleteCat(int id) { Cat cat = db.Cats.Find(id); if (cat == null) { return NotFound(); } db.Cats.Remove(cat); db.SaveChanges(); return Ok(cat); } protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } private bool CatExists(int id) { return db.Cats.Count(e => e.Id == id) > 0; } }
試しに Windows アプリからこんなコードでアクセスして、画面に表示させてみると
/// <summary> /// ボタンクリックイベントハンドラ /// </summary> /// <param name="sender">イベント発行者</param> /// <param name="e">イベント引数</param> public async void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) { var client = new HttpClient(); try { var response = await client.GetStringAsync(new Uri(@"http://localhost:64283/api/Cats")); this.ViewModel.Data = response; } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } }
無事 JSON データが取得できました