2

概要

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の生成に近づけることは可能ですか? どのように?それを実現するには、データベース設計にどのような変更を加える必要がありますか?

4

1 に答える 1

1

今、私たちはこのようなプロジェクトに取り組んでいます... 私があなたの意味を正しく理解し、私があなただったら... 以下のようにデータベース設計として継承された構造を実装しました。クラスは継承ですが、データベースの設計はそうではありません。

TextBoxのIdを削除し、同時にControlIdを PK と FK として配置しました。(FKだけではありません)。

実際、ControlId はTextBoxのPKDynamicControlのFKの両方であり、 PasswordControlTextArea の場合も同様です。

そして今 、TextBoxのControlIdはIdentityではありません。DynamicControlからControlIdを取得 します。

ここに画像の説明を入力

設計オプション Bも受け入れます。設計オプション Aを使用するよりも常に快適です。私の考えでは、それは真実であり、主な構造です。

于 2013-05-03T13:07:20.383 に答える