0

I'm new in OData. I created simple OData project. I have controller. It returns products from DB. To increase performance I'm loading only properties (using System.Linq.Dynamic) when client request contains select row. Here is my controller:

  MainContext Context = null;

    public IHttpActionResult Get(ODataQueryOptions<Product> queryOptions, CancellationToken cancellationToken)
    {
        if (Context == null)
            Context = MainContext.CreateInstance();
        var entities = Context.GetEntities<Product>();
        if (queryOptions.RawValues?.Select != null)
        {
            var selectedProperties = GetSelectedPropertiesFromSelectRaw(queryOptions.RawValues.Select, typeof(Product));
            if (selectedProperties.Any())
            {
                var splittedProperties = string.Join(",", selectedProperties);
                var onlyProperties = entities.Select($"new({splittedProperties})");
                var dynamicInstances = GetInstancesDynamicly(onlyProperties, onlyProperties.ElementType, cancellationToken);
                return Ok(dynamicInstances);
            }
        }
        var entityInstances = CreateInstances(entities, cancellationToken);
        return Ok(entityInstances);
    }

    List<string> GetSelectedPropertiesFromSelectRaw(string selectRaw, Type entityType)
    {
        var properties = selectRaw.Split(',').Select(s => s.Trim())
              .Where(s => s != "" && entityType.GetProperties().Any(p => p.Name == s));

        return properties.ToList();
    }

    private List<Product> CreateInstances(IQueryable<Product> entities, CancellationToken cancellationToken)
    {
        var list = new List<Product>();
        foreach (Product entity in entities)
        {
            cancellationToken.ThrowIfCancellationRequested();
            list.Add(entity);
        }
        return list;
    }

    IList GetInstancesDynamicly<T>(IQueryable entities, T type, CancellationToken cancellationToken) where T : Type
    {
        Type genericListType = typeof(List<>).MakeGenericType(type);
        var list = (IList)Activator.CreateInstance(genericListType);
        foreach (var entity in entities)
        {
            cancellationToken.ThrowIfCancellationRequested();
            list.Add(entity);
        }
        return list;
    }

When I request https://localhost:44326/Products it returns products: result

But when I request https://localhost:44326/Products?$select=Id,Name it is not returning anything. I putted breakpoint before return Ok(dynamicInstances); dynamicInstances contains items:

result2

EDIT: My OData model registration:

   public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        ODataModelBuilder builder = new ODataConventionModelBuilder();
        builder.EntitySet<Product>("Products");
        config.MapODataServiceRoute(
        routeName: "ODataRoute",
        routePrefix: null,
        model: builder.GetEdmModel());
    }

Why it isn't loading anything ?

Dilshod K
  • 2,924
  • 1
  • 13
  • 46

0 Answers0