缺少现有导航属性

时间:2013-07-08 15:29:52

标签: c# asp.net-mvc asp.net-web-api odata

我目前正在检查已经存在的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(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-&gt; Country和User-&gt; Relation存在,但缺少Relation与Country和User的关联。但是,在数据库中,这些关系确实存在并且外键已到位。当我在NuGet控制台中运行Update-Database时,我也收到通知,说明没有代码更新要做。

我已经删除了整个数据库,让CodeFirst重新创建所有内容;更新到OData的最新稳定版本(从4.0.0到4.0.30506),但唉,没有任何工作。

有人有任何线索让我关注吗?提前谢谢!

1 个答案:

答案 0 :(得分:2)

当您的班级标记为[DataContract]时,模型构建器仅选择标记为[DataMember]的公共属性。所以,我不确定模型构建器如何在Country上找出导航属性RelationUser

您当然可以明确告诉模型构建器它无法推断的任何导航属性。示例代码,

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

其他方法是在导航属性上添加DataMember属性,让模型构建器自动识别它们。