Given a model with an entity, and a complex object. When we limit ordering in the complex object it doesn't get respected and the following query succeeds instead of returning bad request.
"/odata/QueryLimitCustomers?$orderby=HomeAddress/ZipCode"
Model, controller and ODataConfig:
```
private static IEdmModel GetModel()
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
EntitySetConfiguration<QueryLimitCustomer> customers = builder.EntitySet<QueryLimitCustomer>("QueryLimitCustomers");
//Can limit sorting and filtering primitive properties
var name = customers.EntityType.Property(p => p.Name);
name.IsNonFilterable();
name.IsUnsortable();
//Can override the behavior specified by the attributes for primitive properties
customers.EntityType.Property(p => p.Age).IsFilterable().IsSortable();
//Can limit sorting and filtering for complex properties.
customers.EntityType.ComplexProperty(p => p.HomeAddress).IsNonFilterable().IsUnsortable();
//Can override the behavior specified by the attributes for complex properties.
customers.EntityType.ComplexProperty(p => p.BusinessAddress).IsFilterable().IsSortable();
ComplexTypeConfiguration<QueryLimitAddress> address = builder.ComplexType<QueryLimitAddress>();
//Can limit sorting and filtering for some of the properties of a complex type.
address.Property(p => p.Street).IsNonFilterable().IsUnsortable();
//Can override the behavior specified by the attributes on properties of a complex type.
address.Property(p => p.Country).IsFilterable().IsSortable();
//Can limit navigation of relationships
customers.EntityType.HasMany(c => c.Orders).IsNotNavigable().IsNotExpandable();
customers.EntityType.HasOptional(c => c.CreditScore).IsNotNavigable().IsNotExpandable();
EntitySetConfiguration<QueryLimitOrder> orders = builder.EntitySet<QueryLimitOrder>("QueryLimitOrders");
EntitySetConfiguration<QueryLimitOrderDetails> ordersdetails = builder.EntitySet<QueryLimitOrderDetails>("QueryLimitOrdersDetails");
EntitySetConfiguration<QueryLimitCreditScore> creditScores = builder.EntitySet<QueryLimitCreditScore>("QueryLimitCreditScores");
return builder.GetEdmModel();
}
public class QueryLimitCustomersController : ODataController
{
[Queryable(PageSize = 10, MaxExpansionDepth = 2)]
public IHttpActionResult Get()
{
return Ok(Enumerable.Range(0, 10).Select(i => new QueryLimitCustomer
{
Id = i,
Name = "Name " + i,
AlternativeAddress = new QueryLimitAddress
{
City = "City " + i,
Country = "Country " + i,
Street = "Street " + i,
ZipCode = i
},
BusinessAddress = new QueryLimitAddress
{
City = "City " + i,
Country = "Country " + i,
Street = "Street " + i,
ZipCode = i
},
HomeAddress = new QueryLimitAddress
{
City = "City " + i,
Country = "Country " + i,
Street = "Street " + i,
ZipCode = i
},
Orders = Enumerable.Range(0, i).Select(j => new QueryLimitOrder
{
Id = i * 10 + j,
PurchasedOn = DateTime.Parse("11/24/2013").Subtract(TimeSpan.FromDays(i * 10 + j))
}).ToList(),
CreditScore = new QueryLimitCreditScore { Id = i, CreditScore = i * 50 }
}));
}
}
public class QueryLimitCustomer
{
public int Id { get; set; }
public string Name { get; set; }
public string MiddleName { get; set; }
[NonFilterable]
[Unsortable]
public string LastName { get; set; }
[NonFilterable]
[Unsortable]
public int Age { get; set; }
public QueryLimitAddress HomeAddress { get; set; }
[NonFilterable]
[Unsortable]
public QueryLimitAddress AlternativeAddress { get; set; }
[NonFilterable]
[Unsortable]
public QueryLimitAddress BusinessAddress { get; set; }
public ICollection<QueryLimitOrder> Orders { get; set; }
public QueryLimitCreditScore CreditScore { get; set; }
}
public class QueryLimitOrder
{
public int Id { get; set; }
public DateTime PurchasedOn { get; set; }
public ICollection<QueryLimitOrderDetails> Details { get; set; }
}
public class QueryLimitCreditScore
{
public int Id { get; set; }
public int CreditScore { get; set; }
}
public class QueryLimitOrderDetails
{
public int Id { get; set; }
public double Value { get; set; }
}
public class QueryLimitAddress
{
public string Street { get; set; }
public int ZipCode { get; set; }
[NonFilterable]
[Unsortable]
public string City { get; set; }
[NonFilterable]
[Unsortable]
public string Country { get; set; }
}
}
```
"/odata/QueryLimitCustomers?$orderby=HomeAddress/ZipCode"
Model, controller and ODataConfig:
```
private static IEdmModel GetModel()
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
EntitySetConfiguration<QueryLimitCustomer> customers = builder.EntitySet<QueryLimitCustomer>("QueryLimitCustomers");
//Can limit sorting and filtering primitive properties
var name = customers.EntityType.Property(p => p.Name);
name.IsNonFilterable();
name.IsUnsortable();
//Can override the behavior specified by the attributes for primitive properties
customers.EntityType.Property(p => p.Age).IsFilterable().IsSortable();
//Can limit sorting and filtering for complex properties.
customers.EntityType.ComplexProperty(p => p.HomeAddress).IsNonFilterable().IsUnsortable();
//Can override the behavior specified by the attributes for complex properties.
customers.EntityType.ComplexProperty(p => p.BusinessAddress).IsFilterable().IsSortable();
ComplexTypeConfiguration<QueryLimitAddress> address = builder.ComplexType<QueryLimitAddress>();
//Can limit sorting and filtering for some of the properties of a complex type.
address.Property(p => p.Street).IsNonFilterable().IsUnsortable();
//Can override the behavior specified by the attributes on properties of a complex type.
address.Property(p => p.Country).IsFilterable().IsSortable();
//Can limit navigation of relationships
customers.EntityType.HasMany(c => c.Orders).IsNotNavigable().IsNotExpandable();
customers.EntityType.HasOptional(c => c.CreditScore).IsNotNavigable().IsNotExpandable();
EntitySetConfiguration<QueryLimitOrder> orders = builder.EntitySet<QueryLimitOrder>("QueryLimitOrders");
EntitySetConfiguration<QueryLimitOrderDetails> ordersdetails = builder.EntitySet<QueryLimitOrderDetails>("QueryLimitOrdersDetails");
EntitySetConfiguration<QueryLimitCreditScore> creditScores = builder.EntitySet<QueryLimitCreditScore>("QueryLimitCreditScores");
return builder.GetEdmModel();
}
public class QueryLimitCustomersController : ODataController
{
[Queryable(PageSize = 10, MaxExpansionDepth = 2)]
public IHttpActionResult Get()
{
return Ok(Enumerable.Range(0, 10).Select(i => new QueryLimitCustomer
{
Id = i,
Name = "Name " + i,
AlternativeAddress = new QueryLimitAddress
{
City = "City " + i,
Country = "Country " + i,
Street = "Street " + i,
ZipCode = i
},
BusinessAddress = new QueryLimitAddress
{
City = "City " + i,
Country = "Country " + i,
Street = "Street " + i,
ZipCode = i
},
HomeAddress = new QueryLimitAddress
{
City = "City " + i,
Country = "Country " + i,
Street = "Street " + i,
ZipCode = i
},
Orders = Enumerable.Range(0, i).Select(j => new QueryLimitOrder
{
Id = i * 10 + j,
PurchasedOn = DateTime.Parse("11/24/2013").Subtract(TimeSpan.FromDays(i * 10 + j))
}).ToList(),
CreditScore = new QueryLimitCreditScore { Id = i, CreditScore = i * 50 }
}));
}
}
public class QueryLimitCustomer
{
public int Id { get; set; }
public string Name { get; set; }
public string MiddleName { get; set; }
[NonFilterable]
[Unsortable]
public string LastName { get; set; }
[NonFilterable]
[Unsortable]
public int Age { get; set; }
public QueryLimitAddress HomeAddress { get; set; }
[NonFilterable]
[Unsortable]
public QueryLimitAddress AlternativeAddress { get; set; }
[NonFilterable]
[Unsortable]
public QueryLimitAddress BusinessAddress { get; set; }
public ICollection<QueryLimitOrder> Orders { get; set; }
public QueryLimitCreditScore CreditScore { get; set; }
}
public class QueryLimitOrder
{
public int Id { get; set; }
public DateTime PurchasedOn { get; set; }
public ICollection<QueryLimitOrderDetails> Details { get; set; }
}
public class QueryLimitCreditScore
{
public int Id { get; set; }
public int CreditScore { get; set; }
}
public class QueryLimitOrderDetails
{
public int Id { get; set; }
public double Value { get; set; }
}
public class QueryLimitAddress
{
public string Street { get; set; }
public int ZipCode { get; set; }
[NonFilterable]
[Unsortable]
public string City { get; set; }
[NonFilterable]
[Unsortable]
public string Country { get; set; }
}
}
```