哪一个是更好的数据设计或对象模型?

时间:2013-05-03 10:17:30

标签: sql-server sql-server-2008 entity-framework oop database-design

概述

我正在设计一种机制,用于在使用ADO.NET Entity Framework的ASP.NET MVC应用程序中生成动态控件。但是,我的问题与MVC无关,与实体框架有点关系。它是关于比较两个对象模型。

问题陈述

在我的应用中,用户必须能够与网页A 进行互动,以指定他想要将此类和此类HTML控件添加到网页B

接下来,当他浏览网页B 时,他必须看到这些控件并能够使用它们。

什么挑战

我已将代码写入生成控件。这很容易。我使用了Tag Builder,Partial Views,HtmlHelper扩展和Display&编辑模板。

挑战 挑战在于实现数据库设计和实体框架生成的对象模型,以保存有关需要生成的控件的元数据。

我提出了如下所示的数据库设计:

Database Diagram

您可以忽略用户权限表。它们与我们的讨论无关。

实体框架基于上述数据库设计生成以下实体。

Entity Framework Model based on the database design

我们将我的数据库设计称为设计选项A

我本来想要一个看起来更像这样的设计:

An Object Model I Would Have Liked To Have: A More Intuitive Option

我们将第二个设计称为设计选项B

第二个选项的代码(精简版)如下所示:

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)是否有可能让实体框架接近生成设计选项B ?怎么样?为实现这一目标,我需要对数据库设计做出哪些更改?

1 个答案:

答案 0 :(得分:1)

现在我们正在公司工作这样的项目...... 如果我的意思正确,如果我是你...我实现了继承结构作为我的数据库设计,如下所示。 现在,您的类是继承,但您的数据库设计不是。

我已删除 TextBox 中的 ID ,并且我已同时将 ControlId 作为PK和FK。 (不仅仅是FK)。

事实上, TextBox 的ControlId PK DynamicControl FK 对于 PasswordControl TextArea

也是如此

现在 TextBox 中的 ControlId 不是身份。从 DynamicControl

获取 ControlId

enter image description here

我也接受设计选项B 。我总是比使用设计选项A 更舒服。在我的想法中它是真实的主结构