概述
我正在设计一种机制,用于在使用ADO.NET Entity Framework的ASP.NET MVC应用程序中生成动态控件。但是,我的问题与MVC无关,与实体框架有点关系。它是关于比较两个对象模型。
问题陈述
在我的应用中,用户必须能够与网页A 进行互动,以指定他想要将此类和此类HTML控件添加到网页B 。
接下来,当他浏览网页B 时,他必须看到这些控件并能够使用它们。
什么不挑战
我已将代码写入生成控件。这很容易。我使用了Tag Builder,Partial Views,HtmlHelper扩展和Display&编辑模板。
挑战 挑战在于实现数据库设计和实体框架生成的对象模型,以保存有关需要生成的控件的元数据。
我提出了如下所示的数据库设计:
您可以忽略用户和权限表。它们与我们的讨论无关。
实体框架基于上述数据库设计生成以下实体。
我们将我的数据库设计称为设计选项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 一样好,但它会涉及一些小方法来做一些事情。例如,要获取下拉列表的所有选项,设计选项A 中的DropDownList类上没有导航属性。我将不得不写一个关于Linq查询的回合来做这件事。
3)是否有可能让实体框架接近生成设计选项B ?怎么样?为实现这一目标,我需要对数据库设计做出哪些更改?
答案 0 :(得分:1)
现在我们正在公司工作这样的项目...... 如果我的意思正确,如果我是你...我实现了继承结构作为我的数据库设计,如下所示。 现在,您的类是继承,但您的数据库设计不是。
我已删除 TextBox 中的 ID ,并且我已同时将 ControlId 作为PK和FK。 (不仅仅是FK)。
事实上, TextBox 的ControlId PK , DynamicControl 的 FK 对于 PasswordControl 和 TextArea
也是如此现在 TextBox 中的 ControlId 不是身份。从 DynamicControl
获取 ControlId
我也接受设计选项B 。我总是比使用设计选项A 更舒服。在我的想法中它是真实的主结构