我有一个表单,其中包含一个字段,我希望用户输入两次以确认其中没有任何错字(例如通常使用密码完成)。支持表单的类在声明中包括以下内容:
[Display(Name = "Citation Number")]
[StringLength(20)]
[Required]
public string CitationNum { get; set; }
[NotMapped]
[Display(Name = "Confirm Citation Number")]
[Compare(nameof(CitationNum), ErrorMessage = "Data entered does not match.")]
public string ConfirmCitationNum { get; set; }
在使用表单中的数据时,这非常有用,我具有所需的验证,并且[NotMapped]
DataAnnotation使得该字段的数据不需要驻留在数据库中。
但是,现在,我正在尝试在表单之外操作数据,它引发了“实体验证”错误,因为当我尝试保存该实体时,检索到的实体列表对该字段没有任何内容。我意识到我可以在保存之前在实体中设置该属性,但这使我认为可能有更好的方法。
是否有更好的方法在表单上进行验证字段并作为实体处理对数据的更新,还是我只需要将未映射的属性手动设置为每次我想匹配的属性操纵一组记录?
答案 0 :(得分:1)
这是避免将实体传递给视图的几种原因之一。这些是不同的关注点,需要变通办法以使EF忽略数据,但又要满足视图的行为需求。对于实体数据来自现有实体的CitationNum的CitationNum和确认投影的视图,应使用视图模型。
public class SomeEntity
{
[Key]
public int SomeEntityId { get; set; }
public string CitationNum { get; set; }
// ...
}
[Serializable]
public class SomeEntityViewModel
{
public int SomeEntityId { get; internal set; }
[Display(Name = "Citation Number")]
[StringLength(20)]
[Required]
public string CitationNum { get; set; }
[Display(Name = "Confirm Citation Number")]
[Compare(nameof(CitationNum), ErrorMessage = "Data entered does not match.")]
public string ConfirmCitationNum { get; set; }
}
然后在为视图准备数据时
var viewModel = context.SomeEntities.Where(x => x.SomeEntityId == someEntityId)
.Select(x => new SomeEntityViewModel
{
SomeEntityId = x.SomeEntityId,
CitationNum = x.CitationNum,
ConfirmCitationNum = x.CitationNum,
// ...
}).Single();
利用可以通过单个ProjectTo
调用完成的自动映射器。