MVC 3:使用EF生成的类作为强类型模型

时间:2011-06-20 14:46:59

标签: c# entity-framework asp.net-mvc-3 viewmodel

this question后,我正在使用一个简单的ViewModel类来测试将强类型模型传递给视图。虽然达林对我原来问题的回答已经解决了我遇到的问题,但现在让我不知所措,为什么我不能用EF生成的课做同样的事情。这就是我所拥有的:

public ActionResult Test()
{
    using (MyEntities db = new MyEntities())
    {
        var model = from c in db.Categories
                    select new CategoryViewModel { CategoryID = c.CategoryID, Name = c.Name };

        return View(model.ToList());
    }
}

这是CategoryViewModel:

public class CategoryViewModel
{
    public int CategoryID { get; set; }
    public string Name { get; set; }
}

在我看来,我只是在模仿这个模型。这产生了期望的结果。但是,EF为我生成的其中一个类是Category。我最初尝试使用它来构建强类型模型并将其传递给视图,如下所示:

public ActionResult Test()
{
    using (MyEntities db = new MyEntities())
    {
        var model = from c in db.Categories
                    select new Category { CategoryID = c.CategoryID, Name = c.Name };

        return View(model.ToList());
    }
}

这给了我以下错误:

“无法在LINQ to Entities查询中构造实体或复杂类型'MyProjectModel.Category'。”

所以我的问题是,除了为我生成的类别之外,CategoryViewModel和Category之间有什么区别?什么阻止我在这种情况下使用Category作为我的模型类型?我今天一直在寻找其他问题(和答案),但我一直无法找到讨论这个问题的东西。我还看到了那些帖子中提到的其他一些新术语(伙伴类,自动化程序,POCO),但是如果不理解我的问题的基础,看看它们是不成熟的。

我真的很感激一些见解。

1 个答案:

答案 0 :(得分:1)

虽然我不知道为什么我打赌实体框架不喜欢在你正在编写查询的属性中选择相同类型的new个对象。如果我的假设是正确的,那么下面的代码应该等同于你要做的事情:

public ActionResult Test()
{
    using (MyEntities db = new MyEntities())
    {
        var model = from c in db.Categories;

        return View(model.ToList());
    }
}

当您将上下文的类的属性映射到另一个类(IE不是由EF生成的类)时,您只需要选择新对象。

我对这个问题进行了一些研究,包括自己复制,根据堆栈跟踪,抛出异常的地方:System.Data.Objects.ELinq.ExpressionConverter.CheckInitializerType(Type type) 以下是CheckInitializerTypefound here)的源代码:

 // Determines whether the given type is supported for materialization
    private void CheckInitializerType(Type type)
    {
        // nominal types are not supported
        TypeUsage typeUsage;
        if (_funcletizer.RootContext.Perspective.TryGetType(type, out typeUsage))
        {
              BuiltInTypeKind typeKind = typeUsage.EdmType.BuiltInTypeKind;
              if (BuiltInTypeKind.EntityType == typeKind ||
                  BuiltInTypeKind.ComplexType == typeKind)
              {
                  throw EntityUtil.NotSupported(System.Data.Entity.Strings.ELinq_UnsupportedNominalType(
                            typeUsage.EdmType.FullName));
              }
        }

        // types implementing IEnumerable are not supported
        if (TypeSystem.IsSequenceType(type))
        {
             throw EntityUtil.NotSupported(System.Data.Entity.Strings.ELinq_UnsupportedEnumerableType(
                        DescribeClrType(type)));
        }
   }

由于我尚未确定的原因,如果您尝试投影属性的对象具有BuiltInTypeKind EntityTypeComplexType,则不支持投影。通过我的测试,我发现我可以将属性投影到使用另一个edmx文件生成的实体上,因此与给定ObjectContext的关系似乎可归结为装饰该System.Data.Objects.DataClasses.EdmEntityTypeAttribute的{​​{1}}。生成实体类。