11

私はこの問題に頭を悩ませています。私はそれについてインターネット上で何かを見つけましたが、明確な答えはありません。私の問題:

MVC3 Web アプリの Model セクションにクラスを作成する必要があります: ParentClass と ChildClass ParentClass には、List 型のプロパティ Children があります。

私は EF Code First を使用しました。これは、データベース内に親テーブルと子テーブルを適切に生成します。

ここで、List または単一の ParentClass を返す REST サービスが必要です。

プロパティ Children を ParentClass から削除しても問題はありません。しかし、そこにプロパティ Children があると、エラーが発生し続けます。

エラー:"The type System.Data.Entity.DynamicProxies.ParentClass_A0EBE0D1022D01EB84B81873D49DEECC60879FC4152BB115215C3EC16FB8003A was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically."}

いくつかのコード:

クラス:

     public class ParentClass
{
    public int ID { get; set; }
    public string Name {get;set;}
    public virtual List<ChildrenClass> Children { get; set; }

}

public class ChildrenClass
{
    public int ID { get; set; }
    public string MyProperty { get; set; }
}

サービス:

[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(IncludeExceptionDetailInFaults = true)] 
public class MyService
{

    static MyContext db;
    public MyService() { db = new MyContext(); }


    [WebGet(UriTemplate = "")]
    public List<ParentClass> GetParents()
    {
        var result = db.Parents.ToList();
        return result;

    }

このサービスを呼び出すと、結果が得られません。私は何を間違っていますか?

4

3 に答える 3

12

コンテキスト構成で DisableProxyCreation を使用する必要がありました。

[OperationContract] 
[WebGet(UriTemplate = "")] 
public List<ParentClass> GetParents() 
{ 
     using (DBContext context = new DBContext()) 
     {
         context.Configuration.ProxyCreationEnabled = false; 
         List<ParentClass> parents = context.Parents
             .Include("Children") 
             .ToList();
         return parents; 
      }
}

これはうまくいきました。

于 2011-11-18T16:34:34.883 に答える
0

場合によっては、公開されるすべてのプロパティが既知の型になるようにラッパー クラスを使用するのが簡単な解決策です。

通常、とにかくコントローラー クラスで ObjectContext または DbContext を使用することはないので、以前のレイヤー (ビジネスまたはサービス レイヤー) では、DB からのオブジェクトから ViewModel スタイル オブジェクトへの迅速な変換を行うことができます。 MVC アプリで行いますが、それらをビューに渡す代わりに、呼び出し元に返します。

すべての場合に使用できるわけではありませんが、多くの場合、実行可能な妥協案です。

于 2012-05-11T17:58:19.903 に答える
0

POCO のプロキシ クラスをシリアル化しているようです。私の最初の推奨事項は、proxydatacontractresolver を使用することです: http://msdn.microsoft.com/en-us/library/system.data.objects.proxydatacontractresolver.aspx

また、Web サービスを介して送信するためのデータをロードするときに、物事を明示的に説明することに取り組みます...つまり

親クラスをに変更

public class ParentClass
{
    public int ID { get; set; }
    public string Name {get;set;}
    public List<ChildrenClass> Children { get; set; }

}

コンテンツを変更して遅延読み込みをオフにする: Entity Framework 4 で遅延読み込みをデフォルトで無効にする

また、回線経由で送信されるデータを返すときに、何をロードするかを明示的に指定します。

[WebGet(UriTemplate = "")]
public List<ParentClass> GetParents()
{
    var result = db.Parents.Include("Children").ToList();
    return result;

}

次の回答をご覧ください: Entity Framework Code First - Eager Loading not working as expected? より高度なインクルード呼び出し用。

また、経験からのアドバイスとして、データ クラスは Web サービスのコンシューマーとのコントラクトを形成するため、ネットワーク経由でデータ クラスを返すことはありません。データ値をマップするクラスの別のセットを用意することをお勧めします。

そうすれば、データ クラスが変更されても、明示的に必要とされない限り、Web サービス クライアントを変更する必要はありません。

また、親クラスまたは子クラスで数千行が予想される場合は、ページングの使用が重要です。それ以外の場合は、N + 1 選択になります。次を参照してください: SELECT N + 1 とは? .

于 2011-11-18T01:10:46.603 に答える