2011-06-20 107 views
0

this question開始,我使用一個簡單的ViewModel類來測試將強類型模型傳遞給視圖。雖然Darin對我原來的問題的回答已經解決了我所遇到的問題,但現在讓我撓頭,爲什麼我不能用EF生成的課程做同樣的事情。下面是我有:MVC 3:使用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; } 
} 

在我看來,我只是foreaching在模型。這產生了期望的結果。然而,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()); 
    } 
} 

這是給我下面的錯誤:

「的實體或複雜類型'MyProjectModel.Category'不能在LINQ to Entities查詢中構建。「

所以我的問題是,CategoryViewModel和Category之外的區別是爲我生成的區別是什麼?什麼阻止我在這種情況下使用Category作爲我的模型類型?我一直在關注今天的其他問題(和答案),但我一直無法找到討論這個問題的東西。我還看到了那些帖子中提到的其他一些新術語(buddy classes,automappers,POCO),但在不瞭解我的問題基礎的情況下查看它們的內容似乎爲時過早。

我真的很感謝一些見解。

回答

1

雖然我不知道爲什麼我敢打賭,實體框架不喜歡在您正在編寫查詢的屬性中選擇相同類型的new對象。如果我的假設是正確下面的代碼應該是等同於你正在嘗試做的事:

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

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

你只需要在你映射的上下文的類的屬性,另一個類選擇新的對象(即不一個由EF生成)。

我做多一點研究的問題,其中包括複製它自己,根據堆棧跟蹤這就是異常被拋出:System.Data.Objects.ELinq.ExpressionConverter.CheckInitializerType(Type type) 下面是CheckInitializerType的源代碼(found 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))); 
     } 
    } 

由於我尚未確定的原因,如果您嘗試投影屬性的對象具有BuiltInTypeKindEntityTypeComplexType,則不支持投影。通過我的測試,我發現我可以將屬性投影到由另一個edmx文件生成的實體上,因此與給定ObjectContext的關係似乎歸結爲裝飾生成的實體類的System.Data.Objects.DataClasses.EdmEntityTypeAttribute

+0

嗨Nathan,這確實有效,但它從表中檢索所有數據。我想要的是,雖然我的示例沒有顯示這一點,但只需選擇幾列並返回它們的數據。我有一個很大的Articles表,裏面有很多字段,有時我只需要幾個字段。我不想從數據庫中提取不必要的數據。我使用分類表作爲一個簡單的測試。:) –

+0

我想我明白你想要做什麼,但看起來問題的癥結在於仍然選擇由EF生成的新對象。如果你只需要幾列,你可能最好使用另一個類,而只使用你關心的那些屬性(或者至少只是將它限制在你感興趣的對象中,比如var model = from db in db。類別where c.IsActive select c;' - 至少那會返回符合條件的行。 –

+0

Thanks Nathan。對於慢速回復感到抱歉,我很感謝你的回答和評論,但我不願意接受你的回答,因爲它仍然沒有告訴我爲什麼會出現這種情況 –