viewmodels需要密钥吗?

我有我的视图模型:

namespace projInterview.Models { public class QuestionViewModel { public piQuestion Question { get; set; } public List Answers { get; set; } public piQuestionFavorite QuestionFavorite { get; set; } public piQuestionLevel QuestionLevel { get; set; } public QuestionViewModel(piQuestion question, List answers ) { Question = question; Answers = answers; } } } 

VM是一个独立的类。 我没有把它带到控制器上。

在我的控制器中:

 namespace projInterview.Controllers { public class QuestionController : Controller { private ProjectContext db = new ProjectContext(); public ActionResult Edit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } piQuestion piquestion = db.piQuestions.Single(x => x.QuestionID == id); List piAnswers = db.piAnswers.Where((x => x.QuestionID == id)).ToList(); var questionViewModel = new QuestionViewModel(piquestion,piAnswers); return View(questionViewModel); } } 

当我到达这一行:

 piQuestion piquestion = db.piQuestions.Single(x => x.QuestionID == id); 

我收到以下错误:

在模型生成期间检测到一个或多个validation错误:

projInterview.DAL.QuestionViewModel :: EntityType’QuesuesViewModel’没有定义键。 定义此EntityType的键。 questionViewModels:EntityType:EntitySet’proviewViewModels’基于类型’QuestionViewModel’,没有定义键。

piQuestionpiAnswer都具有视图模型正在使用的原始模型中的键。 我做错了什么?

等等 。 视图模型与Entity框架上下文完全无关。 它不应该与它相关联。 你现在看来的是db.piQuestions是一个IQueryable ,这是一个绝对错误的事情。 视图模型对EF没有任何了解,EF对视图模型一无所知。

切勿将您的视图模型映射到任何数据库或EF内容。 您将作为IQueryable属性添加到DBContext的是域模型。 这些是绑定到数据库表的模型。

然后在您的控制器操作中,您对数据库(DbContext)进行一次或多次调用,以便检索这些域模型中的一个或多个。 然后,将这些域模型映射(复制属性)到单个视图模型。 最后,将视图模型传递给视图。

另外作为旁注,视图模型通常具有默认构造函数。 您不需要那些采用参数的特定构造函数。 如果您尝试将此类视图模型作为控制器操作的参数,那么这将使默认模型绑定器变得疯狂。

因此得出结论:视图模型没有任何键。 他们甚至不知道钥匙是什么。 密钥是您的数据访问层特有的内容,也就是您的域模型。

为了完成:在View scaffolder中选择模型时,需要一个域模型,因此它还预先填充了Data上下文类,因此它需要一个键。 选择视图模型时,只需删除预填充的DAL类,并将DAL字段留空。

查看脚手架

如果你实际上为viewmodel定义了一个键,正如我错误地做的那样,脚手架将viewmodel的定义添加到上下文类中。 为了弥补我所做的混乱,我从上下文类中删除了viewmodel定义,并从我的viewmodels中删除了键。

我终于从这个答案中得到了这个想法。