$Select query in OData does not list the userdefined datatype unless user defined datatype is added to $expand query

Kamal 1 Reputation point
2022-12-08T10:08:35.247+00:00

I'm using OData Version 2.0

I would need to get all my root level property on response data type while using $Select query in my oData query url. But $select query respond only for primitive data types like (Int, String, DateTime) and custom defined class objects are not listed in the response.

Eg:

My controller section method:

      [HttpGet]  
        [Route("~/api/Test({tenantId})/GetTestProperties")]  
        [UnitOfWork]  
        public IQueryable<TestDataTypeResult> GetTestProperties(long tenantId)  
        {  
            var expand = GetExpandedEntityNames();  
  
            return _testobj.GetTestProperties(tenantId, expand);  
        }  
  
  
  
 public class TestDataTypeResult  
    {  
        public TestDataTypeResult()  
        {  
            
                Matprop = new MatTest();  
        }  
  
        [JsonProperty(Order = 1)]  
        public virtual DateTime TestDate { get; set; }  
  
        [JsonProperty(Order = 2)]  
        public virtual DateTime TestCustDate1{ get; set; }  
  
        [JsonProperty(Order = 3)]  
        public virtual string TestString{ get; set; }  
  
        [JsonProperty(Order = 4)]  
        public virtual int TestInteger { get; set; }  
  
        [JsonProperty(Order = 5)]  
        public HitTest Matprop { get; set; }  
    }  
  
Class   
  
 public class HitTest  
    {  
        [JsonProperty]  
        public string MatString { get; set; }  
  
        [JsonProperty]  
        public int MatInt { get; set; }  
  
        [JsonProperty]  
        public DateTime MatDateTime { get; set; }  
  
        [JsonProperty]  
        public List<string> MatList { get; set; }  
        public MatTest()  
        {  
            MatList = new List<string>();  
            MatString = "Test";  
            MatDateTime = DateTime.Now;  
            MatInt = 0;  
        }  
    }  

When i use the below select query in my api, i get only TestDate & TestDate1, i dont see Matprop is listing in the response unless i add Matprop to $expand as shown in 2nd query.

GetTestProperties?$select=TestDate,TestDate1,Matprop   
GetTestProperties?$select=TestDate,TestDate1,Matprop&$expand=Matprop  

Question: Will user defined data type will be listed in the OData V2.0 $Select query or only primitive data types are listed in response?

Thanks in advance
Kamal.

ASP.NET API
ASP.NET API
ASP.NET: A set of technologies in the .NET Framework for building web applications and XML web services.API: A software intermediary that allows two applications to interact with each other.
294 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. QiYou-MSFT 4,306 Reputation points Microsoft Vendor
    2022-12-09T06:18:41.58+00:00

    Hi @Kamal ,
    Yes, your Matprop is a variable of HitTest, and HitTest is a collection of entities. Usually in OData, $expand is used when it comes to entity collections, which is like expanding the entity collection. For example, there is a class Category, and then there is an entity collection Product below it:

     public class Category  
        {  
            public int ID { get; set; }  
            public string Name { get; set; }  
            public virtual ICollection<Product> Products { get; set; }  
        }  
      
    public class Product  
    {  
        public int ID { get; set; }  
        public string Name { get; set; }  
        public decimal Price { get; set; }  
      
        [ForeignKey("Category")]  
        public int CategoryId { get; set; }  
        public Category Category { get; set; }  
      
        [ForeignKey("Supplier")]  
        public string SupplierId { get; set; }  
        public virtual Supplier Supplier { get; set; }  
    }  
    

    Since you also have an entity collection Supplier under your Category class, and your command is

    GET http://localhost/odata/Categories?$expand=Products  
    

    And you get the result:

    {  
      "odata.metadata":"http://localhost/odata/$metadata#Categories",  
      "value":[  
        {  
          "Products":[  
            {"ID":1,"Name":"Hat","Price":"15.00","CategoryId":1,"SupplierId":"CTSO"},  
            {"ID":2,"Name":"Scarf","Price":"12.00","CategoryId":1,"SupplierId":"CTSO"},  
            {"ID":3,"Name":"Socks","Price":"5.00","CategoryId":1,"SupplierId":"FBRK"}  
          ],  
          "ID":1,  
          "Name":"Apparel"  
        },  
        {  
          "Products":[  
            {"ID":4,"Name":"Yo-yo","Price":"4.95","CategoryId":2,"SupplierId":"WING"},  
            {"ID":5,"Name":"Puzzle","Price":"8.00","CategoryId":2,"SupplierId":"WING"}  
          ],  
          "ID":2,  
          "Name":"Toys"  
        }  
      ]  
    }  
    

    You will find that only the Supplier entity collection is not displayed in the entire category, while the others are displayed. When you want to display this entity collection as well, use commands

      GET http://localhost/odata/Categories?$expand=Products,Supplier  
    

    When you only need to display the Supplier entity collection and nothing else, you can use the command:

    GET http://localhost/odata/Products?$select=Supplier&$expand=Supplier  
    

    To sum up, expand means to expand the collection of entities, but if you only use expand, the other properties of the class will be displayed together, and to display only one entity collection, you must use select and expand together. At the same time, you cannot expand and display the entity collection directly with select.

    Best Regards
    Qi You

    0 comments No comments

  2. Kamal 1 Reputation point
    2022-12-13T18:34:57.32+00:00

    @QiYou-MSFT

    Appreciate your response. I still have needed one more clarification. In my case i'm using Microsoft.Aspnet.WebApi.OData nuget package which uses Odata 2.0 protocols. Also this supplier is a complex type and not a collection.

    If I upgrade my solution to Microsft.Aspnet.OData which uses OData 4.0 protocols can I retrieve the complex type objects without using $expand query in query url.

    //Current   
    GET http://localhost/odata/Products?$select=Supplier&$expand=Supplier  
      
    //Expecting to provide same result as current  
    GET http://localhost/odata/Products?$select=Supplier  
    

    Note : Supplier is Complex data type. I'm getting all primitive data types values without using $expand query and only for complex data type i dont get result without using $expand query in query url

    Thanks,
    Kamal.