2011-06-20 1 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によって私のために生成されたクラスの1つは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とカテゴリ以外のカテゴリは私のために生成されているの違いは何ですか?このシナリオでモデルタイプとしてカテゴリを使用できない原因は何ですか?私は今日、他の質問(および回答)を見てきましたが、私はこれについて議論する何かを見つけることができませんでした。私はまた、これらの記事(バディクラス、オートマッパー、POCO)で言及されているいくつかの新しい用語を見てきましたが、私の問題の基礎を理解することなく、

私は本当にいくつかの洞察に感謝します。

答えて

1

エンティティフレームワークで、同じタイプのオブジェクトを同じタイプのオブジェクトを選択することが好まれない理由を正確にはわかりませんが、クエリを書き出しています。私の仮定は、以下のコードは、あなたがやろうとしているものと同等であるべき正しい場合:

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

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

あなたが別のクラスにあなたのコンテキストのクラスのプロパティをマッピングしているときにのみ、IE(新しいオブジェクトを選択する必要はありませんでしょう1つはEFによって生成される)。

// 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))); 
     } 
    } 
:ここ System.Data.Objects.ELinq.ExpressionConverter.CheckInitializerType(Type type)CheckInitializerTypeのソースコード( found here)です:

は、私は、例外がスローされますこれはスタックトレースによると、それを自分自身を複製するなど、問題に少しより多くの研究をしました

私がまだ決定していない理由は、プロパティを投影しようとしているオブジェクトがBuiltInTypeKindEntityTypeまたはComplexType)の場合、投影はサポートされていません。私のテストでは、別のedmxファイルで生成されたエンティティにプロパティを投影できることを発見しました。そのため、ObjectContextとの関係は、生成されたEntityクラスを装飾するSystem.Data.Objects.DataClasses.EdmEntityTypeAttributeになっています。

+0

こんにちはNathan、実際には動作しますが、テーブルからすべてのデータを取得します。私が望んだのは、ここの例ではこれを示していませんが、ほんの数個の列を選択してデータを返すことです。私はそれに多くのフィールドを持っているはるかに大きな記事のテーブルがあり、私はそれらのカップルが必要な時があります。私はデータベースから不要なデータを取り出すことを望まなかった。私は簡単なテストとしてCategoryテーブルを使用していました。:) –

+0

私はあなたがしようとしていることを理解していると思うが、あなたの問題の要点はまだEFによって生成された新しいオブジェクトを選択しているようだ。いくつかのカラムだけが必要な場合は、関係するプロパティだけを持つ別のクラスを使うのが一番良いかもしれません(あるいは、少なくとも 'var model = from c in db 'のような興味のあるオブジェクトに制限してください)。カテゴリc.IsActive select c; ' - 少なくともあなたの条件を満たす行だけを返します。 –

+0

Thanks Nathan。遅い応答に申し訳ありません。あなたの回答とコメントに感謝しますが、私はあなたの答えを受け入れることを嫌いです。 –

関連する問題