【问题标题】:Existing navigation properties missing缺少现有的导航属性
【发布时间】:2013-07-09 21:51:49
【问题描述】:

我目前正在检查 OData 在现有 Web Api 项目上的可能性。使用 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 and User->Relation存在,但是Relation与Country和User的关联缺失。然而,在数据库中,这些关系确实存在并且外键就位。当我在 NuGet 控制台中运行 Update-Database 时,我还会收到没有代码更新要做的通知。

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

有没有人可以让我跟踪?提前致谢!

【问题讨论】:

  • 在 $metadata 文档中,Relation 类型定义是否具有引用TestProject_Models_User_Relation_TestProject_Models_Relation_RelationPartner 关联的导航属性?我假设 User 类型定义确实有这样的导航属性。

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


【解决方案1】:

当您的类被标记为[DataContract] 时,模型生成器仅选择标记为[DataMember] 的公共属性。所以,我不太确定模型构建器是如何计算出User 上的导航属性CountryRelation

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

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 属性,让模型构建器自动计算它们。

【讨论】:

  • 你的第一个建议就是那个!我假设将[DataMember] 添加到导航属性并不重要,因为我认为它不是严格意义上的属性(这当然是愚蠢的)。另外因为用户没有这些属性,我认为将它们添加到关系中并不重要。但它确实有帮助,非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 1970-01-01
  • 1970-01-01
  • 2011-09-11
  • 2016-12-05
  • 2019-09-11
  • 1970-01-01
相关资源
最近更新 更多