概述
我正在设计一种机制,用于在使用 ADO.NET 实体框架的 ASP.NET MVC 应用程序中生成动态控件。但是,我的问题与 MVC 无关,与实体框架无关。它是关于比较两个对象模型。
问题陈述
在我的应用程序中,用户必须能够与网页 A进行交互,以指定他想要向网页 B添加这样和这样的 HTML 控件。
当他接下来浏览网页 B时,他必须看到这些控件并且能够使用它们。
什么不是挑战
我已经编写了代码来生成控件。那是容易的部分。我使用了 Tag Builder、Partial Views、HtmlHelper 扩展和 Display & Editor 模板。
挑战 挑战在于实现由实体框架生成的数据库设计和对象模型,以保存有关需要生成的控件的元数据。
我想出了一个数据库设计,如下所示:
您可以忽略User和Permissions表。它们与我们的讨论无关。
Entity Framework 基于上述数据库设计生成以下实体。
让我们将我的数据库设计称为Design Option A。
我本来想要一个看起来更像这样的设计:
让我们将第二个设计称为设计选项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一样好,但它会涉及一些迂回的方式来做一些事情。例如,要获取下拉列表的所有选项,Design Option A中的 DropDownList 类没有导航属性。我将不得不编写一个循环的 Linq 查询来做到这一点。
3)是否有可能让实体框架接近生成设计选项 B?如何?为了实现这一目标,我需要对我的数据库设计进行哪些更改?