11

私はこの問題を克服しようとしています。私はそれについてインターネット上で何かを見つけましたが、明確な答えではありません。私の問題:ParentClassオンParentClassとChildClass は私がきちんと親を生成EFコードファーストを、使用EFコード付きWebApi親子関係を持つときに最初にエラーが発生する

List型のプロパティの子供があり :私はMVC3のWebアプリケーションのモデルセクションのクラスに持って

テーブルと私のための子テーブルをデータベースに格納します。

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

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

エラー:"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; } 
} 

サービス:ときに、このサービスcallinh

[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; 

    } 

私は結果を得ることはありません。私は間違って何をしていますか?

答えて

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; 
     } 
} 

これは罰金私のために働きました。

+0

私が探していたもの。これを無効にすることの欠点を知っていますか? – hooked82

+1

プロキシからは、更新情報などを把握することができます。文を含むことを忘れてもエラーはありません。私はまだプロキシエンティティをシリアライズするための解決策がありません –

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; } 

} 

に遅延ロードをオフにするためにあなたのコンテンツを変更: Disable lazy loading by default in Entity Framework 4

ワイヤで送信されているデータを返すときに読み込むものを明示的に指定します。

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

} 

さらに高度なIncludeコールについては、次の回答をご覧ください。Entity Framework Code First - Eager Loading not working as expected?

経験から得たアドバイスもありますが、私はあなたのウェブサービスのコンシューマーのための契約を結んでいるので、ワイヤでデータクラスを返すことはありません。データ値をマップする別のクラスのセットを用意することをお勧めします。

あなたのデータクラスが変更された場合、明示的に要求されない限り、Webサービスクライアントを変更する必要はありません。

親クラスまたは子クラスで1000行が必要な場合は、ページングを使用することが重要です。それ以外の場合は、N + 1選択に終わります。What is SELECT N+1?を参照してください。

+1

私はDataContractResolverを試しましたが、それは助けになりませんでした。 disableproxycreationは役に立ちました。しかし、私が正しく理解すれば、POCOをデータベースから分離して、サービスで使用するクラスから分離する必要があります。しかし、各オブジェクトを複製する必要があるわけではありません。つまり、サイト内での使用のためのParentClassと、ビジネスロジックと、サービスでの使用のための別のParentClassを意味します。あまりにも多くのコードを複製していませんか? – Mounhim

+0

私たちは、リソースモデルとドメインモデルを分離するためにDTOとAutomapperを使用しています。これには多くの利点がありますが、別々のバリデーションと別々の構造があります。 – suing

+0

マップ/ xlatsの追加作業やメンテナンスなど、N個の異なる用途に合わせてPOCOを複製するのは非常に難題です。多くの開発者は、POCOを一度慎重に定義し、特に小規模なプロジェクトでデータ転送とデータアクセスの両方に使用するというアプローチをとっています。これがもはや機能しなくなる(スキーマ変更、リファクタリングなど)時が来たら、新しいPOCOを定義し、必要に応じてマッピングを実行する必要があります。この種のシフト/リファクタは、Webクライアントにはまったく影響を与えません。クラスライブラリの.NETコンシューマにとっては本当に問題に過ぎません。例えば。バイナリ扶養家族。 –

0

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

通常そんなに早く層(ビジネスやサービス層)に、とにかくあなたのコントローラクラスでのObjectContextあるいはDbContextを使用されることはありませんあなたはViewModelにスタイルオブジェクトにDBからの物体からの迅速な翻訳を行うことができ、あなたがMVCアプリケーションでやっているのと同じように、ビューに渡すのではなく、呼び出し元に返します。

多分あなたはそれをすべてのケースで使用することはできませんが、しばしばそれは実行可能な妥協です。

関連する問題