视图模型需要密钥吗?

时间:2013-12-28 15:20:47

标签: c# asp.net-mvc

我有我的观点模型:

namespace projInterview.Models
{
    public class QuestionViewModel
    {
        public piQuestion Question { get; set; }
        public List<piAnswer> Answers { get; set; }
        public piQuestionFavorite QuestionFavorite { get; set; }
        public piQuestionLevel QuestionLevel { get; set; }

        public QuestionViewModel(piQuestion question, List<piAnswer> 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<piAnswer> 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);

我收到以下错误:

  

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

     

projInterview.DAL.QuestionViewModel :: EntityType'QuesuesViewModel'   没有定义键。定义此EntityType的键。   questionViewModels:EntityType:EntitySet'searchViewModels'是   基于没有定义键的类型'QuestionViewModel'。

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

2 个答案:

答案 0 :(得分:24)

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

永远不要将您的视图模型映射到任何数据库或EF的东西。您为DBContext添加IQueryable<T>属性的是域模型。这些是绑定到数据库表的模型。

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

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

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

答案 1 :(得分:14)

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

View Scaffolder

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

I finally got the idea from this answer.