Skip to main content

モデルを関連づける

ここではモデル間の関連を操作する方法を説明します。

関連の追加

モデル間の関連はIModelオブジェクトのRelateメソッドで設定可能です。

このメソッドで追加可能なのは参照関連です。所有関連は子要素のモデルと同時に追加する必要があるため、このメソッドで追加することはできません。所有関連と子要素モデルの追加についてはモデルを追加するを参照してください。

public void RelateModels(ICommandContext c, ICommandParams p)
{
// プロジェクトにモデルを作成します
var ucModel = c.App.Workspace.CurrentProject.AddNewRootModel("UseCaseModel");

// 関連端となるモデルを作成します
IModel usecase = ucModel.AddNewModel("UseCases", "UseCase");
usecase.SetField("Name", "追従走行");

IModel actor = ucModel.AddNewModel("Actors", "Actor");
actor.SetField("Name", "ドライバ");

// 関連端となるモデルを関連づけます
usecase.Relate("MainActor", actor);
}

関連の取得

関連オブジェクト(IRelationship)のコレクションはIModelオブジェクトのGetRelationsメソッドで取得できます。このメソッドでは、所有関連、参照関連のどちらも取得できます。

public void GetRelations(ICommandContext c, ICommandParams p)
{
IModel model = c.App.Workspace.CurrentModel;

// 関連を取得します
foreach ( IRelationship useCaseRel in model.GetRelations("UseCases") )
{
// 関連のターゲットのモデルの名前を取得します
var targetName = useCaseRel.Target?.Name;

// アウトプットに出力します
c.App.Output.WriteLine("sample", $"Name: {targetName}");
}
}

関連の削除

モデル間の関連の削除はIModelオブジェクトのUnRelateメソッドを用います。

このメソッドで削除可能なのは参照関連です。所有関連は子要素のモデルと同時に削除する必要があるため、このメソッドで削除することはできません。所有関連と子要素モデルの削除についてはモデルを削除するを参照してください。

public void UnRelate(ICommandContext c, ICommandParams p)
{
// 削除する関連の関連端を取得します
// モデルパスを指定してモデルを取得する場合
IModel useCase = c.App.Workspace.CurrentProject.GetModelByPath("サンプル/ユースケースモデル/追従走行");
IModel actor = c.App.Workspace.CurrentProject.GetModelByPath("サンプル/ユースケースモデル/ドライバ");

// "MainActor"フィールドの関連を削除します
useCase.UnRelate("MainActor", actor);
}

IModelオブジェクトのUnRelateAllメソッドで指定のモデル間のすべての参照関連を削除することもできます。

public void UnRelateAll(ICommandContext c, ICommandParams p)
{
// 削除する関連の関連端を取得します
// モデルパスを指定してモデルを取得する場合
IModel useCase = c.App.Workspace.CurrentProject.GetModelByPath("サンプル/ユースケースモデル/追従走行");
IModel actor = c.App.Workspace.CurrentProject.GetModelByPath("サンプル/ユースケースモデル/ドライバ");

// 指定のモデル間に接続するすべての参照関連を削除します
useCase.UnRelateAll(actor);
}

IRelationshipオブジェクトのUnRelateメソッドでも関連を削除できます。なお、foreach等でループ処理中に削除を行うと、コレクションの内容が途中で変わることにより例外が発生する場合があります。コレクションをToListメソッドで確定しておくことをおすすめします。

public void UnRelate(ICommandContext c, ICommandParams p)
{
IModel model = c.App.Workspace.CurrentModel;

// 関連を取得します
IRelationshipCollection relationships = model.GetRelations("MainActors");
foreach ( IRelationship transition in relationships.ToList() )
{
// 関連先のモデルの名前が`SomeName`の場合は関連を削除する例です
if ( transition.Target.Name == "SomeName" )
{
transition.UnRelate();
}
}
}

関連先の付け替え

IRelationshipオブジェクトのRelateメソッドで関連先のモデルを付け替えることができます。

このメソッドで付け替え可能なのは参照関連です。所有関連の関連端をこのメソッドで追加することはできません。

以下の付け替えが可能です。

  • 関連元、関連先のどちらも付け替える
  • 関連元はそのままで、関連先のみ付け替える
  • 関連先はそのままで、関連元のみを付け替える

以下は、関連先を付け替える例です。

public void ChangeTarget(ICommandContext c, ICommandParams p)
{
// 付け替え対象の関連の関連元を取得します
IModel sourceModel = c.App.Workspace.CurrentModel;

// 新しい関連先となるモデルを取得します
IModel newTargetModel = c.App.Workspace.CurrentProject.GetModelByPath("サンプル/ユースケースモデル/前方監視センサ");

// 関連を取得します
IRelationshipCollection relationships = sourceModel.GetRelations("MainActors");
foreach ( IRelationship transition in relationships )
{
// 関連先のモデルの名前が`ドライバ`の場合は関連先を`前方監視センサ`に付け替える例です
// 関連元は現在の関連元と同じモデルを指定します
if ( transition.Target.Name == "ドライバ" )
{
transition.Relate(sourceModel, newTargetModel, -1, -1);
}
}
}

IRelationshipオブジェクトのRelateメソッドの第3引数、第4引数には、それぞれ新しい関連元の位置、新しい関連先の位置を指定します。

新しい関連元の位置 (sourceIndex)
関連先のモデルが関連元のモデルをフィールド値として保持する位置です。先頭位置を0とするインデックスを指定してください。対応するフィールド値の要素数の範囲外のインデックス(-1、フィールド値の要素数より大きい値など)を指定した場合は末尾に追加されます。

新しい関連先の位置 (targetIndex)
関連元のモデルが関連先のモデルをフィールド値として保持する位置です。先頭位置を0とするインデックスを指定してください。対応するフィールド値の要素数の範囲外のインデックス(-1、フィールド値の要素数より大きい値など)を指定した場合は末尾に追加されます。