Entity Frameworkの継承型を保存できません

.net entity-framework inheritance savechanges table-per-type

質問

私は自分のデータモデルにtype-per-type継承を実装しました(基本的に私のアイテムのための全ての基本情報を持つBaseEntityタイプとBaseEntityアイテムから継承するEmployerタイプをBaseEntityます)。すべてが正しく設定されているように見えますし、エンティティを使用するとき(ADO.net Data ServicesまたはLinqからエンティティへ)、 Employer種類がわかり、問題はないようです。この問題は、新しいEmployerエンティティを作成して保存しようとしたときに始まります。

.AddToEmployer項目ではないように見えるコンテキスト(( AddObjectまたはAddToBaseEntityのみ))。

AddObject("Employer", NewEmployer)を使用すると、以下のエラーメッセージが表示されます。

EntitySet名 'DataEntities.Employer'が見つかりませんでした。

AddToBaseEntity(NewEmployer)を使用すると、次のエラーメッセージが表示されます。

依存操作の有効な順序を決定できません。外部キー制約、モデル要件、またはストア生成値のために、依存関係が存在する可能性があります。

継承を設定する手順を見逃したことはありますか?継承されたオブジェクトを保存するための特別な方法はありますか?何がおかしいのですか?基本的な問題は、 AddToEmployerを使用する必要があるということですが、それを公開するにはどうすればよいですか。クライアントサイドでEmployerタイプを見ることができ、次のようなことができるので、これがオプションではないことは奇妙に思えます。

var NewEmployer = new Employer() - これは、Employer型を問題なく表示できることを示唆しているようです。

受け入れられた回答

私はいくつかのことを変更し、これを機能させることができました。基本的な問題が何であるかは特にわかりませんが、参考のために私がしたことを投稿したいと思いました。

テーブルの再構築:ID / Key列と1つのデータ列だけでテーブルを再構築しました。

余分な自動インクリメントフィールドを削除しました:BaseEntityとEmployerに自動インクリメントIDを持っていました。 Employerの自動インクリメントIDを削除し、Employer.BaseEntityID列と外部キーをBaseEntity.BaseEntityIDに戻しました。 (これが原因であったようですが、私はこれが許可されたという印象の下にありました)

残念ながら、これはエンティティフレームワークの継承クラスがナビゲーションプロパティを持つことができない(すべてのナビゲーションプロパティは基本エンティティになければならない)という問題につながります。


人気のある回答

私の名前はPhaniです。私はADO.NET Data Servicesチームに所属しています。

ResolveNameメソッドとResolveTypeメソッドは、クライアントがサーバーに送信されるペイロードに書き込むタイプ情報と、サーバーからの応答ペイロードがどのようにResolveType化されるかをカスタマイズするのに役立ちます。

それらはあなたがクライアント上で型を解決するのを手助けし、そして多くのシナリオで役に立ちます。

  1. エンティティのタイプ階層は、サーバー上とはクライアント上で異なります。
  2. サービスによって公開されているエンティティタイプは継承に参加しているため、クライアントで派生タイプを使用したいと考えています。

ResolveNameは、サーバーにリクエストを送信するときにResolveName上に配置するエンティティの名前を変更するために使用されます。

このデータモデルを考えます。サーバー上

public class Employee {
    public int EmployeeID {get;set;}
    public string EmployeeName {get;set;}
}

public class Manager:Employee {
    public List<int> employeesWhoReportToMe {get;set;}
}

クライアントを使用してマネージャエンティティタイプのインスタンスを操作する場合、サーバに変更を送信すると、エンティティが継承に参加するときにペイロードにタイプ情報が存在することが期待されます。

context.AddObject("Employees",ManagerInstance ); <-- add manager instance to the employees set.
context.SaveChanges();

ただし、クライアントがこのペイロードをシリアル化するときには、サーバーで予期されているものではないタイプ名として "Employee"を入れます。そのため、クライアントにネームリゾルバを提供する必要があります。

context.ResolveName = delegate(Type entityType){
    //do what you have to do to resolve the type to the right type of the entity on the server
    return entityType.FullName;
}

Type resolverも同じように使われます。

context.ResolveType = delegate(string entitySetName){
    //do what you have to do to convert the entitysetName to a type that the client understands
    return Type.GetType(entitySetName);
}


ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ