当我们生成导航属性时,我们不会重用这些关系。
例如,假设您有简单的模型,
public class Product
{
public int Id { get; set; }
public Supplier Supplier { get; set; }
}
public class Supplier
{
public int Id { get; set; }
public Product[] Products { get; set; }
}
我们生成的导航属性的 $metadata 如下所示,
<NavigationProperty Name="Supplier" Relationship="ProductsService.Models.ProductsService_Models_Product_Supplier_ProductsService_Models_Supplier_SupplierPartner" ToRole="Supplier" FromRole="SupplierPartner" />
<NavigationProperty Name="Products" Relationship="ProductsService.Models.ProductsService_Models_Supplier_Products_ProductsService_Models_Product_ProductsPartner" ToRole="Products" FromRole="ProductsPartner" />
请注意,我们正在生成两个关系而不是一个。我们这样做的原因是要弄清楚两个导航属性是否代表相同的关系是一个难题。以产品和制造商为例。
public class Manufacturer
{
public int Id { get; set; }
public Product[] RawMaterials { get; set; }
public Product[] Produces { get; set; }
}
public class Product
{
public int Id { get; set; }
public Manufacturer[] Producers { get; set; }
public Manufacturer[] Consumers { get; set; }
}
弄清楚 Maufacturer.RawMaterials 和 Product.Consumers 应该共享相同的关系并且 Manufaturer.Produces 和 Product.Producers 应该共享相同的关系并非易事。我们选择不这样做,因为我们认识的客户并没有从这些信息中获得太多收益。
这一切都是因为 OData 使用与实体框架相同的 EDM 模型。Entityframework 需要此信息,因为它将这些关系映射到将成为数据库中的表的关联集。
我们选择不这样做的另一个原因是,这可能会在 OData V4 中消失。在这里查看工作草案(第 23 页和第 57 页会很有趣)。简而言之,OData V4 中 $metadata 中的导航属性看起来更像这样,
<NavigationProperty Name="Category" Type="Self.Category" Nullable="false" Partner="Products" />
请注意,没有关系,也没有关联集。