LiveLinq を使用すると、宣言型の GUI アプリケーションを作成できることに加えて、非 GUI のバッチ処理を宣言型として作成するプログラミングスタイル("ビュー指向プログラミング" とも呼ばれます)も採用することができます。この技術の概要については、「非 GUI コードでライブビューを使用する方法」を参照してください。
LiveLinqIssueTracker デモアプリケーションでは、Batch Processing フォームを使用してこの技術を説明しています。このフォームは、次の2つのアクションを実装します。
次のビューを定義して、アクション (1) を実行します(ここでは、ビューの LiveLinq to DataSet バージョンを示します。Objects バージョンと XML バージョンも同様です)。
C# |
コードのコピー
|
---|---|
_issuesToAssign = from i in issues where i.AssignedTo == 0 join a in _dataSet.Assignments.AsLive() on new { i.ProductID, i.FeatureID } equals new { a.ProductID, a.FeatureID } join i1 in issues on new { i.ProductID, i.FeatureID, a.EmployeeID } equals new { i1.ProductID, i1.FeatureID, EmployeeID = i1.AssignedTo } into g where g.Count() == 0 join e in _dataSet.Employees.AsLive() on a.EmployeeID equals e.EmployeeID select new IssueAssignment { IssueID = i.IssueID, EmployeeID = a.EmployeeID, EmployeeName = e.FullName }; |
次に、このビューに基づいて、単純なコードで操作を実行します。
C# |
コードのコピー
|
---|---|
foreach (IssueAssignment ia in _issuesToAssign) _dataSet.Issues.FindByIssueID(ia.IssueID).AssignedTo = ia.EmployeeID; |
アクション (2) は、次のビューを定義することで実行されます。
コードのコピー
|
|
---|---|
from i in _dataSet.Issues.AsLive() join p in _dataSet.Products.AsLive() on i.ProductID equals p.ProductID join f in _dataSet.Features.AsLive() on new { i.ProductID, i.FeatureID } equals new { f.ProductID, f.FeatureID } join em in _dataSet.Employees.AsLive() on i.AssignedTo equals em.EmployeeID where i.AssignedTo == employeeID && !i.Fixed select i.IssueID; |
操作 (1) や (2) を一度だけ実行する必要がある場合は、ライブビューを使用しても意味がありません。ただし、ここでは、実行するアルゴリズム全体の中のいくつかの手順として、このアクション (1) と (2) を何度も実行するプログラムを記述しているとします。これは、特にサーバー側プログラミングではよくある例です。
ライブビューがない場合は、毎回クエリーし直すか(コストが大きくなります)、何らかのコレクションを作成し、それを処理アルゴリズムの終わりまで維持する必要があります。そのようなコレクションは、手書きコードで維持する必要がある上に、複雑になることが普通です。また、複数のプログラマによって記述され、バグが含まれることもしばしばです。複数のプログラマが別々の機能を記述すれば(アクション (1) や (2) はそのような機能のほんの一例です)、コードの整合性を維持するために、他のプログラマが記述しているコードを把握する必要があります。このような作業の管理は困難です。1年後に新しいアクションや機能が追加される頃には、各部をつなぐロジックが忘れられ、新しいアクションによって破壊されて、複雑なプログラムが作成されるという悪循環が続いていきます。
アクション (1) および (2) は、実際のプロシージャではなく、宣言型ルールです。ルール (1) は、このビューに、実行すべき割り当てが含まれることを述べています。データにどのような変更があっても、また今から1年後や他のどの時期に何が追加されても、このビューには常に必要な割り当てが含まれます。このロジックは、手続き型のロジックではなく宣言型ルールなので、正しいことが保証されます。
また、ルール (1) の動作は高速です。このアクションを毎回異なるデータに対して 1000 回実行したとしても、そのたびに、必要な量のデータだけが、つまり変更の影響を受けるデータだけが再計算されます。必要なインクリメンタルな再計算だけが実行されます。
ルール (2) も同様に宣言型ルールです。これは、計算を繰り返すことなく、変更の影響を受ける部分だけが再計算されるため、高速に実行されます。
アルゴリズムの主要な部分がビュー指向の方法で、(1) と (2) のような一連のルールとしてプログラミングされている場合は、すべてのルールが連携し、ルール間の整合性が自動的に維持されます。このようなビュー/ルールでアルゴリズム全体を表現することが理想的です。それが不可能な場合は、アルゴリズムの一部をこの方法で実装し、残りを通常の手続き型コードで実装します。