概要
ADO.NET Entity Framework を使用する ASP.NET MVC アプリケーションで動的コントロールを生成するメカニズムを設計しています。ただし、私の質問は MVC とは何の関係もなく、Entity Framework とは少し関係があります。これは、2 つのオブジェクト モデルを比較することです。
問題文
私のアプリでは、ユーザーはWeb ページ Aとやり取りして、そのような HTML コントロールをWeb ページ Bに追加したいことを指定できる必要があります。
次にWeb ページ Bをブラウズすると、それらのコントロールが表示され、使用できるようになるはずです。
挑戦ではないもの
コントロールを生成するコードを作成しました。それは簡単な部分でした。Tag Builder、Partial Views、HtmlHelper 拡張機能、および Display & Editor テンプレートを使用しました。
課題 課題は、データベース設計と、生成する必要があるコントロールに関するメタデータを保持するために Entity Framework によって生成されるオブジェクト モデルに到達することです。
以下に示すようなデータベース設計を考え出しました。
UserテーブルとPermissionsテーブルは無視してかまいません。それらは私たちの議論には関係ありません。
Entity Framework は、上記のデータベース設計に基づいて次のエンティティを生成します。
私のデータベース設計をDesign Option Aとしましょう。
次のようなデザインが欲しかったのです。
この 2 番目の設計を設計オプション Bと呼びましょう。
この 2 番目のオプションのコード (簡略化されたバージョン) は次のようになります。
namespace DynamicControls
{
public class DynamicControlGroup
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Controller { get; set; }
public IEnumerable<string> Actions { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public User CreatedByUser { get; set; }
public DateTime CreationDateTime { get; set; }
public User LastModifiedBy { get; set; }
public DateTime ModificationDateTime { get; set; }
// Navigational
public ICollection<DynamicControl<T>> DynamicControls { get; set; }
}
public class DynamicControl<T>
{
public long Id { get; set; } //db Id
public string HtmlId { get; set; }
public bool ValueRequired { get; set; }
public virtual ControlType ControlType { get; protected set; }
// Every control is capable of having a default value but of a different
// type. Most controls have default values of type text (string). The
// multi-select ones (checkboxes, multi-select lists, etc.) have a default
// value of type IEnumerable<string>. So, I want to leave this generic.
// But I am not that hung-up on this. I am fine if I am required to move
// this property DefaultValue from the base class and make it a concrete
// (not generic) property for each individual child class.
// Mostly I just want the heirarchy. And before that, I want to know
// if it is a good idea to model this heirarchy. Or is it better to just
// work with what my Entity Framework produced for my db?
// Should I change my db? I can because I thought-up the design for
// those tables.
public virtual T DefaultValue { get; set; }
// Navigational
public DynamicControlGroup DynamicControlGroup { get; set; }
}
public class TextBox : DynamicControl<string>
{
public override ControlType ControlType
{
get
{
return DynamicControls.ControlType.TextBox;
}
}
public string Label { get; set; }
public int MaxLength { get; set; }
}
public class PasswordControl : TextBox
{
public override ControlType ControlType
{
get
{
return DynamicControls.ControlType.Password;
}
}
}
public class TextArea : TextBox
{
public override ControlType ControlType
{
get
{
return DynamicControls.ControlType.TextArea;
}
}
public int Rows { get; set; }
}
public class DropDownList: DynamicControl<string>
{
public override ControlType ControlType
{
get
{
return ControlType.DropDownList;
}
}
// I want something like this. That I should be able to say
//
// myDropDownListObject.Options...
//
// You'll notice that given my current database design, I have
// no direct way of accessing the options of a, say, drop down list.
// To do that, I have to make a round-about Linq query.
public ICollection<DynamicControlOption> Options { get; set; }
}
public class DynamicControlOption
{
public long Id { get; set; } // db Id
public string OptionHtmlId { get; set; }
public string OptionValue { get; set; }
public string OptionText { get; set; }
// Navigational property
public DynamicControl<IEnumerable<string>> TheControlWhoseOptionIAm { get; set; }
}
public class User
{
}
public class Permission
{
}
public enum ControlType
{
TextBox,
TextArea,
Password,
RadioButton,
Checkbox,
DropDownList,
MultiSelectList,
DatePicker,
TimePicker,
DateTimePicker
}
}
私の質問 1) 設計オプション B の方が良いと思います。私は正しいと感じていますか?
2)設計オプション Aで問題なく作業できることはわかっていますが、いくつかのことを行うには少し回り道が必要です。たとえば、ドロップダウン リストのすべてのオプションを取得するには、デザイン オプション Aの DropDownList クラスにナビゲーション プロパティがありません。そのためには、ラウンド アバウトの Linq クエリを作成する必要があります。
3) Entity Framework をDesign Option Bの生成に近づけることは可能ですか? どのように?それを実現するには、データベース設計にどのような変更を加える必要がありますか?