複数項目の組み合わせでの重複禁止
項目の「重複禁止」は項目ごとの設定で、複数の項目に付けてもそれぞれが独立にチェックされます。「分類A と分類B の組み合わせが重複しない」という条件は作れません。このページは、複合の重複禁止を追加する本体改修の設計メモです。本体の標準機能ではありません。
前提にした現行実装
設定
重複禁止は Column の NoDuplication(bool?)と、重複時のメッセージ MessageWhenDuplicated です(Column.cs)。
チェックの SQL
IfDuplicatedStatements が NoDuplication == true の項目ごとに 1 つずつ SQL を作ります(ResultModel.cs)。値が空(文字列なら空文字、状況なら 0、担当者なら未設定)のときは SQL を作らないので、空欄どうしは重複扱いになりません。SQL は IfDuplicated テンプレートで、条件は 1 項目だけです(IfDuplicated_Body.txt、Column.cs)。
if exists(
select * from "{テーブル}"
where "{テーブル}"."SiteId"={サイトID}
and "{テーブル}"."{項目}"=@{項目}_#CommandCount#
and "{テーブル}"."{IDの列}"<>{レコードID})
begin; rollback; select '...Duplicated...'; return; end;この SQL は作成(CreateStatements)、更新(UpdateStatements)、別サイトへの移動(Move)の文に入ります(ResultModel.cs、L1907、L2187)。
重複の検出
Repository は IfDuplicated の文を 1 つずつ実行し、1 件でも見つかったらその場で Duplicated を返します(Repository.cs)。このとき返す列名は、SQL の select の結果ではなく、その文の最初のパラメーターの名前です。モデルはこの列名で ErrorData を作り(ResultModel.cs)、その列の MessageWhenDuplicated が表示に使われます。
IfDuplicatedStatements は CodeDefiner が Model_IfDuplicatedStatements*.json・_Body.txt から生成するコードです。
設計
データモデル
項目連携(RelatingColumn)と同じく、サイト設定に一覧で持たせます。
[Serializable]
public class CompositeUniqueConstraint : ISettingListItem
{
public int Id { get; set; }
public string Title; // 管理用の名前(例: 部署+社員番号)
public List<string> Columns; // 対象の項目(2 つ以上)
public string MessageWhenDuplicated; // 重複時のメッセージ
public bool? Disabled; // 一時的に無効にする
}
// SiteSettings
public SettingList<CompositeUniqueConstraint> CompositeUniqueConstraints;チェックの SQL
IfDuplicated テンプレートは引数が 5 つで固定なので、項目の数だけ and を並べる SQL を SqlStatement として直接組み立てます。対象の項目の値をパラメーターに入れ、IfDuplicated = true を付けます。
if exists(
select * from "Results"
where "Results"."SiteId"=@SiteId
and "Results"."ClassA"=@ClassA_#CommandCount#
and "Results"."ClassB"=@ClassB_#CommandCount#
and "Results"."ResultId"<>@ResultId)
...IfDuplicatedStatements の末尾で、Disabled でなく項目が 2 つ以上ある設定ごとに文を足します。単一項目の重複禁止はそのまま先に並ぶので、両方あれば単一項目から順にチェックされます。
空の値の扱いも決めます。現行の単一項目と揃えるなら、組み合わせのどれかが空なら文を作りません。
重複時のメッセージ
Repository は最初のパラメーターの名前を列名として返すので、そのままでは組み合わせの最初の項目の MessageWhenDuplicated が使われます。設定ごとのメッセージを出すには、SqlResponse に設定の ID を載せて返すように Repository の IfDuplicated の分岐と、モデルのエラー処理を変えます。
設定 UI
項目連携の設定と同じ形にします(SiteUtilities.cs の RelatingColumnsSettingsEditor・RelatingColumnDialog)。
図を読み込み中…
改修するファイル
| ファイル | 内容 |
|---|---|
Libraries/Settings/CompositeUniqueConstraint.cs | 新規。設定のクラス |
Libraries/Settings/SiteSettings.cs | CompositeUniqueConstraints と保存時の処理 |
App_Data/Definitions/Definition_Code/Model_IfDuplicatedStatements* | 複合のチェックを足す(ResultModel.cs・IssueModel.cs に生成) |
Libraries/DataSources/Repository.cs | どの設定で重複したかを返す |
Models/Sites/SiteUtilities.cs・SiteModel.cs | 一覧・ダイアログ・保存のアクション |
App_Data/Displays/ | 表示名 |
サイト設定の JSON に入るので、サイト設定を API で取得・更新する場合もそのまま含まれます。