我有一个示例项目,一个动态问卷系统,任何管理员都可以在其中创建问卷,然后向其中添加问题组,然后向每个问题组添加问题。
以构成我的 EF 数据上下文的实体的以下 POCO 组为例:
public class Questionnaire
{
public virtual int Id { get; set; }
public virtual string QuestionnaireName { get; set; }
public virtual IList<QuestionGroup> QuestionGroups { get; set; }
}
public class QuestionGroup
{
public virtual int Id { get; set; }
public virtual string GroupName { get; set; }
public virtual int QuestionnaireId { get; set; }
public virtual IList<Question> Questions { get; set; }
}
public class Question
{
public virtual int Id { get; set; }
public virtual string QuestionText { get; set; }
public virtual int QuestionGroupId { get; set; }
public virtual QuestionGroup QuestionGroup { get; set; }
}
我正在通过 WCF 数据服务在我的 Web UI 中访问这些实体,并且想知道在我的视图中为这些实体处理输入的最佳实践(或至少一种更简洁的方式)是什么。以下是我克服这一点的一些想法,但我很难喜欢其中的任何一个,因为它们只是让人感到复杂。
解决方案 1
Question
向我的实体添加一个名为的属性,SubmittedValue
并让我的 EF 数据上下文为Ignore(m => m.SubmittedValue)
this。我将使用此属性Question
在视图级别保留输入值。
我不喜欢的是,我的 POCO 实体具有几乎不相关的属性——我只会SubmittedValue
在 Web UI 的一种情况下使用,而我的 POCO 实体将在其他地方多次使用。
解决方案 2
创建与我的 POCO 具有相同结构的视图模型对象,我们称之为它们QuestionnaireModel
,QuestionGroupModel
并且QuestionModel
- 这些在我的控制器中初始化,并且属性从 POCO 复制到视图模型。在QuestionModel
我添加我的SubmittedValue
属性并使用自定义模型绑定器保留此值时,该绑定器查看绑定上下文并从视图中获取我的值 - 其中名称类似于 [group.question.1] (其中 1 是问题的 ID )。这在视图中使用每个问题组和每个问题的编辑器模板呈现。
我不喜欢的是,这些额外的视图模型对象使我的 Web UI 膨胀,并且必须手动将属性值从我的 POCO 复制到视图模型。我知道我可以使用 AutoMapper 之类的东西来为我做这件事,但这只是自动化这项工作,理想情况下我根本不想这样做。
解决方案 3
稍微更改解决方案 2,改为扩展我的 POCO 并virtual
用其他视图模型对象覆盖集合属性。所以,我的视图模型看起来像这样:
public class QuestionnaireModel : Questionnaire
{
public new IList<QuestionGroupModel> QuestionGroups { get; set; }
}
public class QuestionGroupModel : QuestionGroup
{
public new IList<Question> Questions { get; set; }
}
public class QuestionModel : Question
{
public string SubmittedValue { get; set; }
}
我最喜欢这个想法,但我还没有真正尝试过。我在这里两全其美:1.我可以将我的 POCO 排除在我的视野之外;2.我将一次性使用属性SubmittedValue
排除在我的业务层之外。
你们有没有更好的方法来处理这个问题?