Entity Framework では、次のモデルがある場合:
class Asset {
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<AssetGroup> Groups { get; set; }
}
class AssetGroup {
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Asset> Assets { get; set; }
}
問題のアセットをロードするためにデータベースにクエリを実行することなく、特定のグループに既存のアセットを追加するのは比較的簡単です。
using(var context = new MyContext()) {
AssetGroup assetGroup = context.AssetGroups.Find(groupId);
// Create a fake Asset to avoid a db query
Asset temp = context.Assets.Create();
temp.Id = assetId;
context.Assets.Attach(temp);
assetGroup.Assets.Add(temp);
context.SaveChanges();
}
ただし、継承階層として実装された複数の資産タイプが存在するようにモデルを拡張したという問題があります。その過程で、Asset クラスは抽象化されました。具体的なタイプのないアセットは意味をなさないからです。
abstract class Asset {
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<AssetGroup> Groups { get; set; }
}
class SpecificAsset1 : Asset {
public string OneProperty { get; set; }
}
class SpecificAsset2 : Asset {
public string OtherProperty { get; set; }
}
問題は、 「抽象クラスのインスタンスを作成できない」Create()
という理由で呼び出しがスローされるInvalidOperationException
ことです。これはもちろん理にかなっています。
では、問題は、データベースからアセットをフェッチしなくても多対多の関係を更新するにはどうすればよいかということです。