私は現在、コードファーストアプローチを使用してエンティティフレームワーク6を使用してasp.netで2つのクラスをモデル化しています。ユーザーはウィジェットを作成できます。ウィジェットには最大5つのWidgetOptionsのコレクションがあります。オプションは主に文字列ですが、他のユーザーとのやりとりが必要なメタデータが関連付けられています(そのため、文字列の集合ではありません)。現在、私のクラスは次のようになっています:私のEF6コードファーストモデルは非常に効率が悪いようですが、改善方法はわかりません。何か不足していますか?
Widget {
public string Name {g;s;}
... //more fields
public string ICollection<WidgetOption> Options {g;s;}
}
WidgetOption {
public string Option {g;s;}
... //more fields
}
これは明らかに単純ですが、私の考えはここにあります。したがって、ユーザーがUIにウィジェットを作成すると、コントローラーは、ユーザーが入力したストリングからWidgetOptionsのリストを作成し、WidgetOptionsをウィジェットに割り当ててから、データベース・コンテキストに保管します。次のように:
Create(WidgetFormViewModel vm) {
var options = vm.WidgetOptions.Select(wo => new WidgetOption(wo)).ToList();
var widget= new Widget {
Options = options,
// ... other fields from vm
};
_context.Widgets.Add(widget);
_context.SaveChanges();
return RedirectToAction("Index", "Home");
}
多くのユーザーがWidgetOption文字列を繰り返す可能性が高いという問題があります。たとえば、多くのユーザーがウィジェットを赤色にするために「赤」という名前を付けることがあります(それは奇妙に思えるかもしれませんが、実際の場合はもっと意味があります)。 Entity Frameworkは現在、WidgetOptionを参照するウィジェット内に列を持たないクラスと、Id、Option、およびWidget_Id列を持つWidgetOptionをモデル化しています。
2人のユーザーが「赤い」WidgetOptionを持つウィジェットを作成すると、WidgetOptionテーブルに2つの行が作成されます。それぞれ固有のIDを持ち、それぞれに対応するWidget_Idを持ちます。これはスペースの点では本当に非効率なようですが、私は間違っている可能性があります(それは私が無駄だと思うほどのスペースではありません)。私は、ユニークなWidgetOption文字列しか持たない別のテーブルを持っていても、Widgetを複数のWidgetOptionsに関連付けるリレーションシップテーブルが必要になると思います。これは、関係テーブルのWidgetOption_Idが文字列自体よりもはるかに小さい場合、現在のモデルよりも効率的である可能性があります。それ以外の場合は、ユーザーが入力した各文字列を検索して、作成されているかどうかを確認する必要があります。だから、私は保存のスピードを犠牲にしています。
私はこれを過度に思っているかどうかはわかりませんが、WidgetOptionsが繰り返されているテーブルを持っていると気が気になります。一意のオプション文字列がわずかであった場合は、多対多の関係がより理にかなっていますが、現在のモデルはすべてのオプション文字列が一意である場合に意味があります。適切な選択は、このスケールのどちらの終わりが実際に起こるかを理解することによってのみ解決できるようです。