Search code examples
c#odataasp.net-web-api

OData without database but with Foreign Keys


I have an OData provider which doesn't use Entity Framework or any other sort of database.

I use the following 2 models:

public class ItemModel : TrackableBaseModel<Item>
{
    [Key]
    public Int32 ItemId { get; set; }

    public String ItemName { get; set; }

    public virtual ICollection<ItemSerialModel> ItemSerials { get; set; }
}


public class ItemSerialModel : TrackableBaseModel<ItemSerial>
{
    public Int32 ItemSerialId { get; set; }

    [ForeignKey("Item")]
    public Int32? ItemId { get; set; }

    public ItemModel Item {get;set; }
}

But the OData $metadata shows:

<EntityType Name="ItemModel">
    <Key>
        <PropertyRef Name="ItemId"/>
    </Key>
    <Property Name="ItemId" Type="Edm.Int32" Nullable="false"/>
    <Property Name="ItemName" Type="Edm.String"/>
    <NavigationProperty Name="ItemSerials" Relationship="UserSite.Models.UserSite_Models_ItemModel_ItemSerials_UserSite_Models_ItemSerialModel_ItemSerialsPartner" ToRole="ItemSerials" FromRole="ItemSerialsPartner"/>
</EntityType>
<EntityType Name="ItemSerialModel">
    <Key>
        <PropertyRef Name="ItemSerialId"/>
    </Key>
    <Property Name="ItemSerialId" Type="Edm.Int32" Nullable="false"/>
    <Property Name="ItemId" Type="Edm.Int32"/>
    <NavigationProperty Name="ItemModel" Relationship="UserSite.Models.UserSite_Models_ItemSerialModel_ItemModel_UserSite_Models_ItemModel_ItemModelPartner" ToRole="ItemModel" FromRole="ItemModelPartner"/>
</EntityType>

But that doesn't make much sense, it comes with ItemModelPartner which doesn't even exist in the project.

How can I setup manual FK's so that the navigation properties will work in OData?

The WebApiConfig defines the models like this:

builder.EntitySet<ItemModel>("Items").EntityType.HasKey(x => x.ItemId);
builder.EntitySet<ItemSerialModel>("ItemSerials").EntityType.HasKey(x => x.ItemSerialId);

Solution

  • Try changing your EdmModel to as follows.

    ODataConventionModelBuilder v1ODataConventionModelBuilder = new ODataConventionModelBuilder();
    
    v1ODataConventionModelBuilder.EntitySet<ItemModel>("ItemModels");
    v1ODataConventionModelBuilder.EntitySet<ItemSerials>("ItemSerials");
    
    config.Routes.MapODataRoute("routename", "routeprefix/", v1ODataConventionModelBuilder.GetEdmModel()
    

    You should also be able to remove the following property

    [ForeignKey("Item")]
    public Int32? ItemId { get; set; }