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

时间:2015-08-20 05:29:18

标签: c# entity-framework asp.net-web-api odata

我的EDMX文件中有大量实体(通过数据库第一设计器创建)。我不想为我想要向我的Odata服务公开的每个实体创建一个单独的Web Api 2控制器。这就是为什么我的任务是创建一个单一的Web Api 2 OData 4控制器来返回属于我的EntityFramework EDMX文件的任何实体的数据。

我创建了一个GetData(db,“实体名称”)方法,以动态地从存储库中为任何实体返回IQueryable。

我的IQueryable< DimUser> Get()方法有效,但IQueryable Get()(没有硬编码的dimUser)却没有。 OK方法不执行任何操作并返回空白结果。

我非常沮丧,因为我没有得到任何错误,我似乎没有弄清楚Ok方法的内部工作原理。

问题

是否可以在我的GenericController类中使用IQueryable Get()方法而不是IQueryable Get()?

通用控制器代码

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;
        }

    }
}

注册方法

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类

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";
        }
    }
}

1 个答案:

答案 0 :(得分:2)

解决方案是使用特定结果类型创建结果实例。见下文

   [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;
    }