简体   繁体   English

Web API 2:OData 4:具有Common Repository的单个控制器在传递给OK方法时不能与IQueryable一起使用

[英]Web API 2: OData 4: Single Controller with Common Repository does not work with IQueryable when passed to the OK method

I have tons of entities (created via Database first designer) within my EDMX file. 我的EDMX文件中有大量实体(通过数据库第一设计器创建)。 I don't want to create a separate Web Api 2 controller for each entity that I want to expose to my Odata service. 我不想为我想要向我的Odata服务公开的每个实体创建一个单独的Web Api 2控制器。 That is why my task is to create a SINGLE Web Api 2 OData 4 Controller to return data for any entity that is part of my EntityFramework EDMX file. 这就是为什么我的任务是创建一个单一的Web Api 2 OData 4控制器来返回属于我的EntityFramework EDMX文件的任何实体的数据。

I created a GetData(db, "entity name") method to return IQueryable for any entity from the repository dynamically. 我创建了一个GetData(db,“实体名称”)方法,以动态地从存储库中为任何实体返回IQueryable。

My IQueryable< DimUser > Get() method works, but IQueryable Get() (without hard-coded dimUser) does not. 我的IQueryable <DimUser> Get()方法有效,但IQueryable Get()(没有硬编码的dimUser)没有。 The OK method does not do anything and returns me blank result. OK方法不执行任何操作并返回空白结果。

I am very frustrated as I don't get any error, and I don't seem to figure out the inner workings of the Ok method. 我很沮丧,因为我没有得到任何错误,我似乎没有弄清楚Ok方法的内部工作原理。

Question

Is is possible to use IQueryable Get() method instead of IQueryable Get() within my GenericController class? 可以在我的GenericController类中使用IQueryable Get()方法而不是IQueryable Get()吗?


Generic Controller Code 通用控制器代码

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.ModelBinding;
using System.Web.OData;
using System.Web.OData.Extensions;
using System.Web.OData.Query;
using System.Web.OData.Routing;


using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Library;

using MyDataAccess;
using System.Reflection;

namespace DataService.Controllers
{
    public class GenericController : ODataController
    {
        private Entities db = new MyDataAccess.Entities();

        //HARD-CODING ENTITY NAME RETURNS RESULT, 
        //(but it is not acceptable solution)

        //[EnableQuery(PageSize = 10)]
        //public IQueryable<DimUser> Get()
        //{
        //    return db.DimUsers;
        //}

        //THIS ONE DOES NOT WORK
        [EnableQuery(PageSize = 10)]
        public IQueryable Get()
        {
            var data = GetData(db,"DimUsers");
            return data;
        }

        // Define other methods and classes here
        public IQueryable GetData(MyDataAccess.Entities db, string EntityName)
        {
            foreach (PropertyInfo property in db.GetType().GetProperties())
            {
    var name = property.Name;
    if (name == EntityName)
    {
        var v = property.GetValue(db);
        return (IQueryable)v;
    }
            }
            return null;
        }

    }
}

Register method 注册方法

public static void Register(HttpConfiguration config)
{
    IList<IODataRoutingConvention> routingConventions = ODataRoutingConventions.CreateDefault();
    routingConventions.Insert(0, new CustomControllerRoutingConvention());
    config.MapODataServiceRoute("EntityDataRoute", "GetEntityData", GenerateEdmModel_Entities(), 
        new DefaultODataPathHandler(), routingConventions);

}

CustomControllerRoutingConvention class CustomControllerRoutingConvention类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web;
using System.Web.OData.Routing;
using System.Web.OData.Routing.Conventions;

namespace DataService
{
    public class CustomControllerRoutingConvention : IODataRoutingConvention
    {
        public string SelectAction(ODataPath odataPath, System.Web.Http.Controllers.HttpControllerContext controllerContext, ILookup<string, System.Web.Http.Controllers.HttpActionDescriptor> actionMap)
        {
            return null;
        }

        public string SelectController(ODataPath odataPath, HttpRequestMessage request)
        {
            return "Generic";
        }
    }
}

The solution is to creates an instance of the result with specific result type. 解决方案是使用特定结果类型创建结果的实例。 see below 见下文

   [EnableQuery(PageSize = 10)]
    public IQueryable Get()
    {
        var data = GetData(db,"DimUsers");
        return Okay(data, data.GetType());
    }




    protected IHttpActionResult Okay(object content, Type type)
    {
        var resultType = typeof(OkNegotiatedContentResult<>).MakeGenericType(type);
        return Activator.CreateInstance(resultType, content, this) as IHttpActionResult;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM