最初に説明と要点、次に質問です。そう:
コードAccountView
生成されたクラスが
//This class is generated from a view by EF (edmx)...
public partial class AccountView
{
public System.Guid Id { get; set; }
public int CompanyId { get; set; }
}
次に、同じ名前空間 ( Entities
)に部分クラスを作成します。
[MetadataType(typeof(AccounViewMetaData))]
public partial class AccounView
{
//This is added here explicitly. AccountView itself exposes just
//a naked key, CompanyId.
public virtual Company Company { get; set; }
//This is just in case...
public class AccounViewDomainMetaData
{
//This is to add a navigation property to the OData $metadata. How to do this
//in WebApiConfig? See as follows...
[ForeignKey("Company")]
public int CompanyId { get; set; }
}
}
と
//This is an EF generated class one from an edmx..-
public partial class Company
{
public Company()
{
}
public int CompanyID { get; set; }
public string Name { get; set; }
}
そしてWebApiConfig
、次のように、OData v4(WebApiを使用した最新の6.9.0.0シリーズ、これも最新)で何かを書く、またはしようとします
builder.EntitySet<Entities.Company>("Companies");
var accountSet = builder.EntitySet<Entities.AccountView>("Accounts");
accountSet.EntityType.HasKey(i => i.Id); //EF has hard time recognizing primary keys on database first views...
//TODO: How should I define the required binding so that I could "?$expand=Company"
//as such as ``http://example.com/service/Accounts?$expand=Company``
//accountSet.HasRequiredBinding(i => i.CompanyId, typeof(Entities.Company));
結果$metadata
は次のようになります
<schema>
<EntityType Name="Company">
<Key>
<PropertyRef Name="CompanyID"/>
</Key>
<Property Name="CompanyID" Type="Edm.Int32" Nullable="false"/>
<Property Name="Name" Type="Edm.String"/>
</EntityType>
<EntityType Name="AccountView">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Guid" Nullable="false"/>
<Property Name="CompanyId" Type="Edm.Int32" Nullable="false"/>
<NavigationProperty Name="Company" Type="Entities.Company" Nullable="false"/>
</EntityType>
</Schema>
質問:コメントで述べたようにTODO
、どのように定義すればよいですか?
http://example.com/Accounts?$expand=Company
orhttp://example.com/Accounts?$Companies
?を呼び出すことができるナビゲーション プロパティ。
今私が呼び出すと動作します
http://example.com/Accounts
またhttp://example.com/Accounts(someId)
次に、次のようなことをすると
http://example.com/Accounts?$expand=Companies
http://example.com/Accounts?$expand=Company
またhttp://example.com/Accounts(someId)?$expand=Company
HTTP 400 (?$expand=Companies) またはHTTP 500 (?$expand=Company) で迎えられます。
Containment
私はすでに関係を築くことに成功しました。ただし、ルート エンティティを ID で定義する必要があるように見えますが、ルートに「GET」を提供し、オプションで「子リスト」オブジェクトに展開したい (したがって、?$expand= に関するこの質問) .
今のケースでは、expand
1 つのエンティティに対して 1 つのオプションではない処理を行っていますが、次に希望するのは、エンティティ (またはこの特定の例に関しては企業) のリストがあるシナリオですが、どうすればこれらを達成できるのでしょうか?シナリオ?最初の常に存在するサブオブジェクトに展開するこのケースでも修正するにはどうすればよいですか?
私のコントローラーは次のように定義されています
public class AccountsController: ODataController
{
[EnableQuery]
public IHttpActionResult Get()
{
try
{
//This context here is a EF entities model (generated from an edmx)...
return Ok(Context.AccountView);
}
catch(Exception ex)
{
return InternalServerError();
}
}
[EnableQuery]
public IHttpActionResult Get([FromODataUri]Guid key)
{
try
{
return Ok(SingleResult.Create(Context.AccountView.Where(a => a.Id == key)));
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
}
私が基本的にやろうとしているのは、最初にデータベース、edmx、ビューにいくつかのメタデータを追加し、記事Using $select, $expand, and $value in ASP.NET Web API 2 ODataを模倣することです。これまでのところ成功していません...
<編集 1:いわばプロットが厚くなります。HTTP 500 エラーは、次のような内部例外 (マネージド フレームワーク例外への中断を有効にする必要がありました) から発生します。
タイプ 'System.NotSupportedException' の初回例外が EntityFramework.dll で発生しました
追加情報: 指定された型メンバー 'Company' は、LINQ to Entities ではサポートされていません。初期化子、エンティティ メンバー、およびエンティティ ナビゲーション プロパティのみがサポートされています。
したがって、はい、AccountView
ビューであり、テーブルへの直接の外部キー関係はありませんCompany
(たまたまテーブルですが、ビューでもある可能性があります)。どうすれば追加できますか?情報によって証明されるように、私はメタデータを追加することですでにトリックを行っていました$metadata
。ODataINNER JOIN
はデータベースに を書き込むだけではありませんか? ここで何か不足していますか?...これは、Company
参照を追加した方法に関連しているようで、EFはそれが好きではありません。ODataモデルのみに追加する必要があるようです...
<編集 2:表の定義の大文字と小文字を一致させるために toAccountView
CompanyId
を変更しても (少なくとも私が持っている設定では) 違いはないようです。CompanyID
Company
<edit3:これに関連する別の質問をしました。How to add complex properties on a model built with an ODataConventionModelBuilder from an EF model .