LiveLinq によって提供されるライブビューは、データ連結シナリオに限定されません。
ライブビューを使用して、複数のテーブルから取得したデータを組み合わせ、このデータをビジネスルールに従ってグループ化して集計し、さらにすべての時点でアプリケーションから使用可能にします。ビューは常にデータと同期化されており、データが必要なときに何らかのメソッドを呼び出してビューを更新する必要はありません。これにより、アプリケーションロジックが大きく簡略化され、効率が向上します。
この点を具体的に説明するために、次のサービスを公開する NorthWind アプリケーションを考えます。
ProcessOrder:このサービスは、顧客に課金し、製品を出荷し、またデータベース内の情報を更新します。これは、営業部門および自社の Web ストアで使用されます。
SalesInformation:このサービスは、製品および製品カテゴリごとの売上の要約を返します。管理部門とマーケティング部門で使用されます。
ProcessOrder サービスで注文を直接データベースに書き込み、SalesInformation サービスで最新の販売サマリーを返すストアドプロシージャを実行することで、このアプリケーションを実装できます。これでも機能しますが、SalesInformation サービスは毎回データベースにアクセスし、データベース内のすべての注文をスキャンするため、比較的大きな負荷が発生します。
別のアプローチとして、データをライブビューにロードし、そこで注文の処理に従って販売サマリーを常に最新の状態を維持する方法があります。ProcessOrder メソッドを呼び出すと、SalesInformation によって提供されるサマリーが自動的に更新されます。SalesInformation の呼び出しは、データベースにまったくアクセスすることなく、即座に処理されます。
これを説明するために、再度 NorthWind データを使用して、別の単純な WinForms アプリケーションを作成します。このアプリケーションには3つのグリッドを置きます。最初の1つは ProcessOrder サービスに対応するグリッドで、注文を編集するために使用されます。他の2つは SalesInformation サービスに対応するグリッドで、販売サマリーが常に注文に同期して表示されます。
手順は次のとおりです。
次に、フォームを右クリックし、次のコードを入力します。
C# |
コードのコピー
|
---|---|
using C1.LiveLinq; using C1.LiveLinq.AdoNet; using C1.LiveLinq.LiveViews; public Form1() { InitializeComponent(); // データを取得します NORTHWNDDataSet ds = GetData(); // 受注明細を更新するためのライブビューを作成します this.dataGridView1.DataSource = GetOrderDetails(ds); // 最新の受注情報を提供するライブビューを作成します this.dataGridView2.DataSource = GetSalesByCategory(ds); this.dataGridView3.DataSource = GetSalesByProduct(ds); } |
前と同様に、最初の手順ではデータベースから関連データをロードします。
C# |
コードのコピー
|
---|---|
NORTHWNDDataSet GetData() { var ds = new NORTHWNDDataSet(); new NORTHWNDDataSetTableAdapters.ProductsTableAdapter() .Fill(ds.Products); new NORTHWNDDataSetTableAdapters.Order_DetailsTableAdapter() .Fill(ds.Order_Details); new NORTHWNDDataSetTableAdapters.CategoriesTableAdapter() .Fill(ds.Categories); return ds; } |
次に、LiveLinq を使用して、SalesInformation サービスから公開されるライブビューを実装します。これは標準の LINQ クエリーです。ただし、標準のクエリーをライブビューに変換するための2つの AsLive 節があり、以前のサンプルで使用した LINQ クエリーより多少高度になっています。
C# |
コードのコピー
|
---|---|
object GetSalesByCategory(NORTHWNDDataSet ds) { var products = ds.Products; var details = ds.Order_Details; var categories = ds.Categories; var salesByCategory = from p in products.AsLive() join c in categories.AsLive() on p.CategoryID equals c.CategoryID join d in details.AsLive() on p.ProductID equals d.ProductID let detail = new { CategoryName = c.CategoryName, SaleAmount = d.UnitPrice * d.Quantity * (decimal)(1f - d.Discount) } group detail by detail.CategoryName into categorySales let total = categorySales.Sum(x => x.SaleAmount) orderby total descending select new { CategoryName = categorySales.Key, TotalSales = total }; return salesByCategory; } |
クエリーは、最初に、それぞれ製品、カテゴリ、注文の情報が格納された3つのテーブルを結合します。次に、各受注明細の製品カテゴリと合計額を保持する一時変数 detail を作成します。最後に、明細を総売上に基づいて並べ替え、カテゴリ名でグループ化します。
結果は、基底のデータが変化したときに自動的に更新されるライブビューになります。これは、すぐ後に、アプリケーションを実行して確認します。
次のライブビューは、カテゴリごとではなく、製品ごとに販売情報を提供する点を除けば同じです。
C# |
コードのコピー
|
---|---|
object GetSalesByProduct(NORTHWNDDataSet ds) { var products = ds.Products; var details = ds.Order_Details; var categories = ds.Categories; var salesByProduct = from p in products.AsLive() join c in categories.AsLive() on p.CategoryID equals c.CategoryID join d in details.AsLive() on p.ProductID equals d.ProductID into sales let productSales = new { ProductName = p.ProductName, CategoryName = c.CategoryName, TotalSales = sales.Sum( d => d.UnitPrice * d.Quantity * (decimal)(1f - d.Discount)) } orderby productSales.TotalSales descending select productSales; return salesByProduct; } |
C# |
コードのコピー
|
---|---|
object GetOrderDetails(NORTHWNDDataSet ds) { var products = ds.Products; var details = ds.Order_Details; var categories = ds.Categories; var orderDetails = from d in details.AsLive().AsUpdatable() join p in products.AsLive() on d.ProductID equals p.ProductID join c in categories.AsLive() on p.CategoryID equals c.CategoryID select new { c.CategoryName, p.ProductName, d.UnitPrice, d.Quantity, d.Discount }; return orderDetails; } |
ここでアプリケーションを実行すると、次のようなウィンドウが表示されます。
このアプリケーションは、カテゴリ別および製品別の総売上を金額でソートして表示します。最もよく売れたカテゴリは "Beverages" であり、最もよく売れた製品は "Cote de Blaye" です。
ここで、上のグリッドにある列ヘッダー[ProductName]をクリックし、"Cote de Blaye" のエントリが見つかるまで下にスクロールします。見つかったら、いくつかの注文を変更して、サマリーデータが直ちに更新されることを確認します。たとえば、いくつかの "Cote de Blaye" 注文の数量をゼロに変更すると、"Beverages" が直ちに "Diary Products" カテゴリの後に移動します。
この単純な例は、LINQ ベースのライブビューの能力を示しています。LINQ ベースのライブビューは、データとロジックの橋渡しとなり、データ中心型アプリケーションを格段に簡潔かつ効率的に作成できるようにします。