カスタムタスクスケジューラシステムを実装しようとしています。次の(簡略化された)エンティティモデルがあります。
class User
{
public virtual long UserId { get; set; }
public virtual string Name { get; set; }
}
class Task
{
public virtual long TaskId { get; set; }
public virtual long? UserId { get; set; }
public virtual string TaskName { get; set; }
public virtual Guid SchedulerSessionUid { get; set; }
}
今のところ、対応するSQLテーブルは単純で、上記のクラスに表示されているとおりにフィールドがマッピングされています。
スケジューラーはC#Windowsコンソールアプリです。1日1回実行されます。次のように機能するはずです(簡略化)。
- 現在のセッションのGUIDを生成する
- 現在のスケジューラセッションでスケジュールされたタスクがまだない次のユーザーエンティティを選択してみてください(GUID比較)。そのようなユーザーが見つからない場合は、手順5に進みます。
- 手順2で選択したユーザーの新しいタスクを追加します。
- 手順2に進みます。
- アプリケーションを終了します
かなり些細な問題のようですが、2番目のステップの実装に問題があります。私はさまざまなクエリを試しましたが、常に私を止めるルールがいくつかあります。
ステップ1を実装する際に従わなければならないいくつかのルールがあります。
- UserクラスまたはUserSQLテーブルを変更することは許可されていません
- 問題の解決に役立つ場合は、タスククラスとテーブルを変更する可能性があります
- 役立つ場合は、新しいテーブルまたはストアドプロシージャを追加できます
- NHibernateおよびLINQと可能な限り互換性のある方法で実装する必要があります
- Userオブジェクトに関連付けられていないタスクも存在する可能性があります(スケジューラーはそれらを無視しますが、SQL / LINQクエリとNHibernateマッピングを設計する際にはそれを覚えておく必要があります)。
これが実際の例です。
Users
-----------------
UserId Name
-----------------
1 First
2 Second
Tasks
--------------------------------------------------------
TaskId UserId SchedulerSessionUid
--------------------------------------------------------
1 NULL 6d8e48d0-4e92-477e-82fa-cd957e7dc201
2 1 d213cfc8-23d6-49fb-b4e3-9ff3b60af6c4
3 1 9ee042df-88a7-447e-adbd-e7551ed50ae5
1.スケジューラが実行されると、現在のセッションID=76ea57fa-8c89-4c05-9ca2-a450b1f8a032が生成されます。
- これで、魔法のLINQクエリをNHibernate LINQプロバイダーに発行して、ユーザーエンティティを取得する必要があります。
- 最初の反復では、そのユーザーの現在のセッションにはまだタスクがないため、クエリはUserId=1のユーザーエンティティを返す必要があります。
- これで、スケジューラーはUserId = 1、SchedulerSessionUid=76ea57fa-8c89-4c05-9ca2-a450b1f8a032で新しいタスクを作成します。
次の反復では、スケジューラーはUserId=2のユーザーを取得する必要があります。ここでも、UserId = 2、SchedulerSessionUid=76ea57fa-8c89-4c05-9ca2-a450b1f8a03で新しいタスクが挿入されます。次の反復では、スケジューラはユーザーを取得しないはずなので、終了します。
手順2のユーザーを取得するために使用できるLINQクエリは何ですか?SQLスキーマとエンティティモデルにどのような変更が必要ですか?