1

私は現在、既存の Web Api プロジェクトで OData の可能性をチェックしている最中です。Code First を使用して、すべてのモデルをゼロから作成しているため、それらを完全に制御できます。ただし、コードにナビゲーション プロパティを追加したにもかかわらず、OData が提供するメタデータ リンクを介してチェックアウトすると、一部のプロパティがスキーマに表示されません。

たとえば、 Person クラスから継承する User クラスがあります。

[DataContract]
[KnownType(typeof(User))]
public abstract class Person
{
    [DataMember]
    public int ID { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public Nullable<int> CountryID { get; set; }
    [DataMember]
    public Nullable<int> RelationID { get; set; }

    public virtual Country Country { get; set; }
    public virtual Relation Relation { get; set; }
}

これで GET リクエストを実行すると、 を使用して/User(1284)/Relation(または/Countryそれについては)、必要な Relation クラスまたは Country クラスが正確に返されます。/Relation(16)/Countryただし、この関連付けが存在しないため、を呼び出すことができないという問題があります。

[DataContract]
public class Relation
{
    [DataMember]
    public int ID { get; set; }
    [DataMember]
    public string Number { get; set; }
    [DataMember]
    public string Serial { get; set; }
    [DataMember]
    public Nullable<int> CountryID { get; set; }

    public virtual Country Country { get; set; }
    public virtual List<User> Users { get; set; }
}

しかし、ご覧のとおり、私のリレーション クラスには、そのようなナビゲーション プロパティが存在することは間違いありません。また、DbContext クラスを見ると、次のようになります。

    public DbSet<Relation> Relations { get; set; }
    public DbSet<Country> Countries { get; set; }
    public DbSet<User> Users { get; set; }

および WebApiConfig

    ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
    modelBuilder.EntitySet<Relation>("Relations");
    modelBuilder.EntitySet<Country>("Countries");
    modelBuilder.EntitySet<User>("Users");

実際、リレーションとユーザーはナビゲーション プロパティに関してほぼ同じであることがわかります。少なくとも国では同じです。

私が言ったように、OData 自体によって提供されるメタデータを見ると、次のようになります。

  <Association Name="TestProject_Models_User_Country_TestProject_Models_Country_CountryPartner">
    <End Type="TestProject.Models.Country" Role="Country" Multiplicity="0..1" />
    <End Type="TestProject.Models.User" Role="CountryPartner" Multiplicity="0..1" />
  </Association>
  <Association Name="TestProject_Models_User_Relation_TestProject_Models_Relation_RelationPartner">
    <End Type="TestProject.Models.Relation" Role="Relation" Multiplicity="0..1" />
    <End Type="TestProject.Models.User" Role="RelationPartner" Multiplicity="0..1" />
  </Association>

User->Country および User->Relation が存在することがわかりますが、Relation to Country および User の関連付けが欠落しています。ただし、データベースにはこれらの関係が存在し、外部キーが配置されています。NuGet コンソールで Update-Database を実行すると、実行するコードの更新がないという通知も表示されます。

データベース全体を既に削除しており、CodeFirst にすべてを再作成させました。OData の最新の安定したビルド (4.0.0 から 4.0.30506 まで) に更新されましたが、残念ながら何も機能していません。

私が従うべき手がかりはありますか?前もって感謝します!

4

1 に答える 1

2

クラスがマークされて[DataContract]いる場合、モデル ビルダーはマークされているパブリック プロパティのみを選択します[DataMember]。そのため、モデル ビルダーがどのようにナビゲーション プロパティCountryRelationonを把握したかはよくわかりませんUser

もちろん、推論できなかったナビゲーション プロパティをモデル ビルダーに明示的に伝えることもできます。サンプルコード、

var relations = modelBuilder.EntitySet<Relation>("Relations");
var countries = modelBuilder.EntitySet<Country>("Countries");
var users = modelBuilder.EntitySet<User>("Users");
users.HasRequiredBinding(u => u.Country, countries);
users.HasRequiredBinding(u => u.Relation, relations);
relations.HasRequiredBinding(r => r.Country, countries);
relations.HasManyBinding(r => r.Users, users);

もう 1 つの方法は、ナビゲーション プロパティにも DataMember 属性を追加して、モデル ビルダーがそれらを自動的に把握できるようにすることです。

于 2013-07-08T20:05:15.597 に答える