【发布时间】:2014-04-08 16:30:18
【问题描述】:
我收到错误消息:
作为 TOP 子句和 LIMIT 子句的参数的参数 不支持查询或命令树中的 LimitExpression 早于 SQL Server 2005 的 SQL Server 版本。
在 LinqPad 中或通过 http 执行 Take() 时使用 WebAPI + oData:
http://localhost:8080/odata/sample()?$top=10
但是,如果我直接对 DbContext 运行 Take(),它可以正常工作。所以我认为 oData 魔法正在创建一些我的设置不支持的 linq / sql。
我遇到的复杂情况是 EDMX 需要设置为在兼容模式 80 (sql 2000) 下运行。
我正在使用Composite Key in ASP.NET Web API OData(但我现在明白那是the recommended approach from another post,所以可能不是问题)。
而且它来自视图,而不是表格。
我使用的是 WebApi 1(不是 2)。
有没有办法覆盖正在生成的 SQL,从而避免不兼容的 SQL?
编辑:
在单步执行 webapi(然后是实体框架代码)——一次启发性的体验之后,我找到了引发异常的那一行:
在\entityframework\src\EntityFramework.SqlServer\SqlGen\Sql8ConformanceChecker.cs中
/// <summary>
/// Walks the structure
/// </summary>
/// <exception cref="NotSupportedException">expression.Limit is DbParameterReferenceExpression</exception>
public override bool Visit(DbLimitExpression expression)
{
Check.NotNull(expression, "expression");
if (expression.Limit is DbParameterReferenceExpression)
{
throw new NotSupportedException(Strings.SqlGen_ParameterForLimitNotSupportedOnSql8);
}
return VisitExpression(expression.Argument);
}
但我仍然不确定为什么我可以轻松地针对上下文执行 OrderBy().Take() 但 oData 版本失败。
我设法比较了 oData 生成的 DbQueryCommandTree 与查询 dbContext 时生成的等效项。
oData 版本:
{DbQueryCommandTree
|_Parameters
| |_p__linq__0 : Edm.Int32
|_Query : Collection{Record['UserID'=Edm.Int32, 'RolledupReviewPeriodID'=Edm.Int32, 'UserEmployeeNumber'=Edm.String, 'FirstName'=Edm.String, 'LastName'=Edm.String, 'JobTitle'=Edm.String, 'CostCentre'=Edm.String, 'CostCentreNo'=Edm.String, 'Department'=Edm.String, 'Division'=Edm.String, 'Directorate'=Edm.String, 'AppraiserName'=Edm.String, 'ReviewDate'=Edm.DateTime, 'Status'=Edm.String, 'InterimRating'=Edm.Int32, 'IndicativeRating'=Edm.Int32, 'PreModerated'=Edm.Int32, 'ModeratedRating'=Edm.Int32, 'FinalRating'=Edm.Int32, 'ReviewPeriodName'=Edm.String]}
|_Project
|_Input : 'Limit1'
| |_Limit
| |_Sort
| | |_Input : 'Extent1'
| | | |_Scan : PMM_ModelStoreContainer.vwReports_ReviewRatings
| | |_SortOrder
| | |_Asc
| | | |_Var(Extent1).RolledupReviewPeriodID
| | |_Asc
| | |_Var(Extent1).UserID
| |_@p__linq__0
|_Projection
|_NewInstance : Record['UserID'=Edm.Int32, 'RolledupReviewPeriodID'=Edm.Int32, 'UserEmployeeNumber'=Edm.String, 'FirstName'=Edm.String, 'LastName'=Edm.String, 'JobTitle'=Edm.String, 'CostCentre'=Edm.String, 'CostCentreNo'=Edm.String, 'Department'=Edm.String, 'Division'=Edm.String, 'Directorate'=Edm.String, 'AppraiserName'=Edm.String, 'ReviewDate'=Edm.DateTime, 'Status'=Edm.String, 'InterimRating'=Edm.Int32, 'IndicativeRating'=Edm.Int32, 'PreModerated'=Edm.Int32, 'ModeratedRating'=Edm.Int32, 'FinalRating'=Edm.Int32, 'ReviewPeriodName'=Edm.String]
|_Column : 'UserID'
| |_Var(Limit1).UserID
|_Column : 'RolledupReviewPeriodID'
| |_Var(Limit1).RolledupReviewPeriodID
|_Column : 'UserEmployeeNumber'
| |_Var(Limit1).UserEmployeeNumber
|_Column : 'FirstName'
| |_Var(Limit1).FirstName
|_Column : 'LastName'
| |_Var(Limit1).LastName
|_Column : 'JobTitle'
| |_Var(Limit1).JobTitle
|_Column : 'CostCentre'
| |_Var(Limit1).CostCentre
|_Column : 'CostCentreNo'
| |_Var(Limit1).CostCentreNo
|_Column : 'Department'
| |_Var(Limit1).Department
|_Column : 'Division'
| |_Var(Limit1).Division
|_Column : 'Directorate'
| |_Var(Limit1).Directorate
|_Column : 'AppraiserName'
| |_Var(Limit1).AppraiserName
|_Column : 'ReviewDate'
| |_Var(Limit1).ReviewDate
|_Column : 'Status'
| |_Var(Limit1).Status
|_Column : 'InterimRating'
| |_Var(Limit1).InterimRating
|_Column : 'IndicativeRating'
| |_Var(Limit1).IndicativeRating
|_Column : 'PreModerated'
| |_Var(Limit1).PreModerated
|_Column : 'ModeratedRating'
| |_Var(Limit1).ModeratedRating
|_Column : 'FinalRating'
| |_Var(Limit1).FinalRating
|_Column : 'ReviewPeriodName'
|_Var(Limit1).ReviewPeriodName}
直接点击dbContext时的版本
{DbQueryCommandTree
|_Parameters
|_Query : Collection{Record['UserID'=Edm.Int32, 'RolledupReviewPeriodID'=Edm.Int32, 'UserEmployeeNumber'=Edm.String, 'FirstName'=Edm.String, 'LastName'=Edm.String, 'JobTitle'=Edm.String, 'CostCentre'=Edm.String, 'CostCentreNo'=Edm.String, 'Department'=Edm.String, 'Division'=Edm.String, 'Directorate'=Edm.String, 'AppraiserName'=Edm.String, 'ReviewDate'=Edm.DateTime, 'Status'=Edm.String, 'InterimRating'=Edm.Int32, 'IndicativeRating'=Edm.Int32, 'PreModerated'=Edm.Int32, 'ModeratedRating'=Edm.Int32, 'FinalRating'=Edm.Int32, 'ReviewPeriodName'=Edm.String]}
|_Project
|_Input : 'Limit1'
| |_Limit
| |_Sort
| | |_Input : 'Extent1'
| | | |_Scan : PMM_ModelStoreContainer.vwReports_ReviewRatings
| | |_SortOrder
| | |_Asc
| | | |_Var(Extent1).RolledupReviewPeriodID
| | |_Asc
| | |_Var(Extent1).UserID
| |_10
|_Projection
|_NewInstance : Record['UserID'=Edm.Int32, 'RolledupReviewPeriodID'=Edm.Int32, 'UserEmployeeNumber'=Edm.String, 'FirstName'=Edm.String, 'LastName'=Edm.String, 'JobTitle'=Edm.String, 'CostCentre'=Edm.String, 'CostCentreNo'=Edm.String, 'Department'=Edm.String, 'Division'=Edm.String, 'Directorate'=Edm.String, 'AppraiserName'=Edm.String, 'ReviewDate'=Edm.DateTime, 'Status'=Edm.String, 'InterimRating'=Edm.Int32, 'IndicativeRating'=Edm.Int32, 'PreModerated'=Edm.Int32, 'ModeratedRating'=Edm.Int32, 'FinalRating'=Edm.Int32, 'ReviewPeriodName'=Edm.String]
|_Column : 'UserID'
| |_Var(Limit1).UserID
|_Column : 'RolledupReviewPeriodID'
| |_Var(Limit1).RolledupReviewPeriodID
|_Column : 'UserEmployeeNumber'
| |_Var(Limit1).UserEmployeeNumber
|_Column : 'FirstName'
| |_Var(Limit1).FirstName
|_Column : 'LastName'
| |_Var(Limit1).LastName
|_Column : 'JobTitle'
| |_Var(Limit1).JobTitle
|_Column : 'CostCentre'
| |_Var(Limit1).CostCentre
|_Column : 'CostCentreNo'
| |_Var(Limit1).CostCentreNo
|_Column : 'Department'
| |_Var(Limit1).Department
|_Column : 'Division'
| |_Var(Limit1).Division
|_Column : 'Directorate'
| |_Var(Limit1).Directorate
|_Column : 'AppraiserName'
| |_Var(Limit1).AppraiserName
|_Column : 'ReviewDate'
| |_Var(Limit1).ReviewDate
|_Column : 'Status'
| |_Var(Limit1).Status
|_Column : 'InterimRating'
| |_Var(Limit1).InterimRating
|_Column : 'IndicativeRating'
| |_Var(Limit1).IndicativeRating
|_Column : 'PreModerated'
| |_Var(Limit1).PreModerated
|_Column : 'ModeratedRating'
| |_Var(Limit1).ModeratedRating
|_Column : 'FinalRating'
| |_Var(Limit1).FinalRating
|_Column : 'ReviewPeriodName'
|_Var(Limit1).ReviewPeriodName}
最大的不同在于它在参数中传递的 oData 版本:
|_Parameters | |_p__linq__0 : Edm.Int32
而 dbcontext 版本的参数只是直接传入,即“10”
【问题讨论】:
标签: sql entity-framework asp.net-web-api entity-framework-6 asp.net-web-api-odata