1
votes

I was reading about OData sources at Odata.org when I ran across this segment about associations.

Associations define the relationship between two or more Entity Types (for example, Employee WorksFor Department). Instances of associations are grouped in Association Sets. Navigation Properties are special properties on Entity Types which are bound to a specific association and can be used to refer to associations of an entity.

Finally, all instance containers (Entity Sets and Association Sets) are grouped in an Entity Container.

Putting the above paragraphs into OData terms, the feeds exposed by an OData service are represented by Entity Sets or a Navigation Property on an Entity Type that identifies a collection of entities. For example, the Entity Set identified by the URI http://services.odata.org/OData/OData.svc/Products or the collection of entities identified by the "Products" navigation property in http://services.odata.org/OData/OData.svc/Categories(1)/Products identifies a feed of entries exposed by the OData service.

I am making a OData service in C# using Visual Studio 2012 and would like to use the URL functionality mentioned. However I do not know how to set it up. Does anybody know how to do this?

Here is my code:

    public class AssociationTest : DataService<ServiceContext>
{
    // This method is called only once to initialize service-wide policies.
    public static void InitializeService(DataServiceConfiguration config)
    {
        config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
        config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
    }
}
public class ServiceContext
{
    CategoryList _categories = new CategoryList();
    public IQueryable<Category> CategorySet
    {
        get{return _categories.AsQueryable();}
    }
    ProductList _products = new ProductList();
    public IQueryable<Product> ProductSet
    {
        get{return _products.AsQueryable();}
    }

}
[System.Data.Services.Common.DataServiceKeyAttribute("ID")]
public class Category
{
    public string Type
    {
        get;
        set;
    }
    public int ID
    {
        get;
        set;
    }
}
public class CategoryList : List<Category>
{
    public CategoryList()
        : base()
    {
        Add(new Category { Type = "Hardware", ID = 0 });
        Add(new Category { Type = "Software", ID = 1 });
    }
}
[System.Data.Services.Common.DataServiceKeyAttribute("ID")]
public class Product
{
    public string Name
    {
        get;
        set;
    }
    public int ID
    {
        get;
        set;
    }
    public int CategoryID
    {
        get;
        set;
    }
}
public class ProductList:List<Product>
{
    public ProductList()
        : base()
    {
        Add(new Product { Name = "Computer", ID = 0, CategoryID = 0 });
        Add(new Product { Name = "Phone", ID = 1, CategoryID = 0 });
        Add(new Product { Name = "Outlook", ID = 2, CategoryID = 1 });
        Add(new Product { Name = "Excel", ID = 3, CategoryID = 1 });
    }
}
1
Are you using WCF Data Services, ASP.NET Web API, or making an OData server by hand?Jen S
If I understand your question correctly, then I think what you want will just work out of the box. For example, if you are using Entity Framework as your provider, following the quick start guide here should result in a service that generates payloads with navigation links like the one in the text you copied. Or am I misunderstanding?Jen S
It is the same idea except I don't want to base my DataService off of an Entity Data Model. I am trying to base it off a class containing IQueryable lists. I'll include some of my code.Ryan K

1 Answers

1
votes

Instead of modeling the relationship between Product->Category with a foreign key, you could have your service model point to the product's category directly. What I mean is that instead of this:

public class Product
{
    // ...
    public int CategoryID
    {
        get;
        set;
    }
}

You could model it like this:

public class Product
{
    // ...
    public Category ProductCategory
    {
        get;
        set;
    }
}

If you set up the model this way, the WCF Data Services reflection provider should automatically create a navigation property on Product as well as the necessary association in the model.