具有相同结果集的多个odata web api控制器

时间:2014-11-30 17:20:04

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

我需要创建两个返回相同结果集的odata控制器。

具体来说,结果集从两个存储过程返回,这两个存储过程接收大量参数,并在服务器上进行一些繁重的处理。

两个SP都接收完全相同的参数并返回相同的数据,但它们以不同的方式完成搜索,我需要进行一些性能测试和比较。

SP映射到EF中的函数。

所以我需要有两个odata控制器,每个控制器调用一个不同的SP,但返回相同的数据类型。

我的代码如下:

控制器1

<Authorize>
Public Class SearchController
    Inherits ODataController

    Private _dc As New ModelDC

    ' GET odata/Search
    <Queryable>
    Function GetSearch(<FromURI> search As SearchParam) As IQueryable(Of SearchResult)
        dim result =  _dc.Search(search.Parm1, search.Param2, ...).ToList
        Return result.AsQueryable
    end function

控制器2

<Authorize>
Public Class SearchV2Controller
    Inherits ODataController

    Private _dc As New ModelDC

    ' GET odata/Search
    <Queryable>
    Function GetSearch(<FromURI> p1 as string, <FromURI> p2 as string, ...) As IQueryable(Of SearchResult)
        dim result =  _dc.SearchV2(p1, p2, ...).ToList
        Return result.AsQueryable
    end function

在WebApiConfig.Register

中注册odata路线
Dim builder As New ODataConventionModelBuilder
builder.EntitySet(Of SearchResult)("Search")
config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel())

builder = New ODataConventionModelBuilder
builder.EntitySet(Of SearchResult)("SearchV2")
config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel())

然而,当我启动应用程序时,我收到以下错误:

  

&#39; /&#39;中的服务器错误应用。类型异常   &#39;的System.OutOfMemoryException&#39;被抛出。描述:未经处理   在执行当前Web请求期间发生异常。   请查看堆栈跟踪以获取有关错误的更多信息   它起源于代码。

     

异常详细信息:System.OutOfMemoryException:类型异常   &#39;的System.OutOfMemoryException&#39;被扔了。

     

来源错误:

     

执行期间生成了未处理的异常   当前的网络请求。有关的来源和位置的信息   可以使用下面的异常堆栈跟踪来识别异常。

     

堆栈追踪:

     

[OutOfMemoryException:类型的异常&#39; System.OutOfMemoryException&#39;   被抛出。] System.Reflection.RuntimeAssembly._nLoad(AssemblyName   fileName,String codeBase,Evidence assemblySecurity,RuntimeAssembly   locationHint,StackCrawlMark&amp; stackMark,IntPtr pPrivHostBinder,   Boolean throwOnFileNotFound,Boolean forIntrospection,Boolean   suppressSecurityChecks)+0
  System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName,String   codeBase,Evidence assemblySecurity,RuntimeAssembly locationHint,   StackCrawlMark&安培; stackMark,IntPtr pPrivHostBinder,Boolean   throwOnFileNotFound,Boolean forIntrospection,Boolean   suppressSecurityChecks)+34
  System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(的AssemblyName   assemblyRef,Evidence assemblySecurity,RuntimeAssembly reqAssembly,   StackCrawlMark&安培; stackMark,IntPtr pPrivHostBinder,Boolean   throwOnFileNotFound,Boolean forIntrospection,Boolean   suppressSecurityChecks)+152
  System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString,   证据集合安全,StackCrawlMark&amp; stackMark,IntPtr   pPrivHostBinder,Boolean forIntrospection)+77
  System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString,   证据集合安全,StackCrawlMark&amp; stackMark,布尔   forIntrospection)+16 System.Reflection.Assembly.Load(String   assemblyString)+28
  System.Web.Configuration.CompilationSection.LoadAssemblyHelper(字符串   assemblyName,布尔starDirective)+38

     

[ConfigurationErrorsException:类型异常   &#39;的System.OutOfMemoryException&#39;被扔了。]
  System.Web.Configuration.CompilationSection.LoadAssemblyHelper(字符串   assemblyName,布尔starDirective)+736
  System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory()   +217 System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo   ai)+130
  System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection   compConfig)+170
  System.Web.Compilation.BuildManager.GetPreStartInitMethodsFromReferencedAssemblies()   +91 System.Web.Compilation.BuildManager.CallPreStartInitMethods(String   preStartInitListPath,Boolean&amp; isRefAssemblyLoaded)+284
  System.Web.Compilation.BuildManager.ExecutePreAppStart()+153
  System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager   appManager,IApplicationHost appHost,IConfigMapPathFactory   configMapPathFactory,HostingEnvironmentParameters hostingParameters,   PolicyLevel policyLevel,Exception appDomainCreationException)+521

     

[HttpException(0x80004005):类型异常   &#39;的System.OutOfMemoryException&#39;被扔了。]
  System.Web.HttpRuntime.FirstRequestInit(HttpContext context)+9930508   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context)   +101 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest)   wr,HttpContext context)+254

有什么问题? 是否两个控制器都定义了相同的返回类型? 当然,我可以为第二个SP(具有完全相同的结构)创建一个不同的实体,并将每个SP的结果映射到不同的结果类,我认为这将起作用,但我更喜欢让它们都返回相同类型的结果。

我做错了什么?

由于

PS。我首先将结果转换为ToList,然后返回AsQueryable,因为我需要支持$ inlinecount odata param,而EF映射的SP使用内部的DataReader,它不允许重新枚举该集合以先获取计数然后返回实际数据。如果有人有更好的想法来解决这个问题,请告诉我。

1 个答案:

答案 0 :(得分:0)

为什么要用不同的Edm模型映射相同的路线?你能把它们合并在一起吗?

Dim builder As New ODataConventionModelBuilder
builder.EntitySet(Of SearchResult)("Search")
builder.EntitySet(Of SearchResult)("SearchV2")
config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel())