Search code examples
c#odatasimple.odata.client

How to expand hierarchical data with simple.odata.client


In our data model we have hierarchical data. We have for example the following structure:

Product  : Category       (one to many)
Category : CategoryType   (one to many)

If we want to have a certain Product's related categories and also each category's related categorytypes we can build this up with a url like this:

<urlbase>/Products(1)?$expand=Category($expand=CategoryType)

This works fine in the browser. The question is how this can be done in the simple.odata.client OData v4? We are trying this but not getting it to to work:

var client = new ODataClient(ConfigSettingsProvider.ODataBaseUri);
var client
    .For<Product>()
    .Filter(p=> p.Id == 1)
    .Expand(p => p.Categories)
    .Expand(c => c.CategoryTypes)
    .FindEntriesAsync();

Solution

  • Please check Simple.OData.Client tests that contain both untyped, typed and dynamic versions:

    Untyped: https://github.com/object/Simple.OData.Client/blob/master/Simple.OData.Client.Tests.Net40/FindTests.cs

    [Fact]
    public async Task ExpandOne()
    {
    var product = (await _client
      .For("Products")
      .OrderBy("ProductID")
      .Expand("Category")
      .FindEntriesAsync()).Last();
    
    Assert.Equal("Condiments", (product["Category"] as IDictionary<string, object>)["CategoryName"]);
    }
    [Fact]
    public async Task ExpandMany()
    {
    var category = await _client
      .For("Categories")
      .Expand("Products")
      .Filter("CategoryName eq 'Beverages'")
      .FindEntryAsync();
    
    Assert.Equal(12, (category["Products"] as IEnumerable<object>).Count());
    }
    [Fact]
    public async Task ExpandSecondLevel()
    {
    var product = (await _client
      .For("Products")
      .OrderBy("ProductID")
      .Expand("Category/Products")
      .FindEntriesAsync()).Last();
    
    Assert.Equal(12, ((product["Category"] as IDictionary<string, object>)["Products"] as IEnumerable<object>).Count());
    }
    

    Typed: https://github.com/object/Simple.OData.Client/blob/master/Simple.OData.Client.Tests.Net40/FindTypedTests.cs

     [Fact]
    public async Task ExpandOne()
    {
    var product = (await _client
      .For<Product>()
      .OrderBy(x => x.ProductID)
      .Expand(x => x.Category)
      .FindEntriesAsync()).Last();
    
    Assert.Equal("Condiments", product.Category.CategoryName);
    }
    [Fact]
    public async Task ExpandManyAsArray()
    {
    var category = await _client
      .For<Category>()
      .Expand(x => x.Products)
      .Filter(x => x.CategoryName == "Beverages")
      .FindEntryAsync();
    
    Assert.Equal(12, category.Products.Count());
    }
    [Fact]
    public async Task ExpandManyAsList()
    {
    var category = await _client
      .For<CategoryWithList>("Categories")
      .Expand(x => x.Products)
      .Filter(x => x.CategoryName == "Beverages")
      .FindEntryAsync();
    
    Assert.Equal(12, category.Products.Count());
    }
    [Fact]
    public async Task ExpandManyAsIList()
    {
    var category = await _client
      .For<CategoryWithIList>("Categories")
      .Expand(x => x.Products)
      .Filter(x => x.CategoryName == "Beverages")
      .FindEntryAsync();
    
    Assert.Equal(12, category.Products.Count());
    }
    [Fact]
    public async Task ExpandManyAsICollection()
    {
    var category = await _client
      .For<CategoryWithICollection>("Categories")
      .Expand(x => x.Products)
      .Filter(x => x.CategoryName == "Beverages")
      .FindEntryAsync();
    
    Assert.Equal(12, category.Products.Count());
    }
    [Fact]
    public async Task ExpandSecondLevel()
    {
    var product = (await _client
      .For<Product>()
      .OrderBy(x => x.ProductID)
      .Expand(x => x.Category.Products)
      .FindEntriesAsync()).Last();
    
    Assert.Equal(12, product.Category.Products.Length);
    }