我正在 ASP.NET MVC 5项目中使用EF 6.1.3。虽然我的开发环境是SQL Server 2012,但QA和生产环境在SQL Server 2008 R2上。
我有一份报告显示医生使用的前 5 个程序代码,所以我有一个简单的实体,其中包含 id、名称、代码 1、代码 2,...代码5.
构建 LINQ 查询时有相当多的逻辑,本质上,我得到一个医生列表和一个代码列表并连接它们。 以下是连接它们并选择前 5 个代码的代码:
var report =
from pr in providerRiskLevels
join nc in newCodes on pr.Provider.ProviderId equals nc.ProviderId
where pr.RiskCategoryId == RIskScoreIds.VisibleRisk
&& (filterRiskLevelNums.Contains(pr.RiskLevelNum))
&& (filterSpecialtyId == 0 || pr.Provider.Specialty.SpecialtyId == filterSpecialtyId)
select new ReportNewCodesEntity
{
ProviderId = pr.Provider.ProviderId,
ProviderName = pr.Provider.Name,
ProviderCode = pr.Provider.ProviderCode,
SpecialtyName = pr.Provider.Specialty.Name,
SpecialtyCode = pr.Provider.Specialty.SpecialtyCode,
RiskScore = pr.RiskScore,
RiskLevelName = pr.RiskLevelName,
RiskLevelNum = pr.RiskLevelNum,
NewCode1 = nc.Codes.OrderByDescending(c => c.Volume).FirstOrDefault().ProcedureCode,
NewCode2 = nc.Codes.OrderByDescending(c => c.Volume).Skip(1).FirstOrDefault().ProcedureCode,
NewCode3 = nc.Codes.OrderByDescending(c => c.Volume).Skip(2).FirstOrDefault().ProcedureCode,
NewCode4 = nc.Codes.OrderByDescending(c => c.Volume).Skip(3).FirstOrDefault().ProcedureCode,
NewCode5 = nc.Codes.OrderByDescending(c => c.Volume).Skip(4).FirstOrDefault().ProcedureCode
};
return report;
问题是,这四种Skip().FirstOrDefault()
使用SQL Server 2008 R2上不可用的语法生成SQL:
OFFSET x ROWS FETCH NEXT 1 ROWS ONLY
其中 x = 1 到 4
我确信我可以将其移动到存储过程中(在 T-SQL 中比在 LINQ 中好得多),但由于我一直在尝试掌握 LINQ,我想知道是否有:
- 告知 LINQ 目标数据库的版本以便生成合规代码的指令
- 提取这些前 5 个代码的另一种方法。
我已经在 newCodes 中正确排序了代码(见下文),但没有 SKIP就无法选择它们(这需要它自己的排序子句)。
var newCodes =
from cc in codeCounts
group cc by
new {cc.ProviderId}
into g
select new ProviderNewCodesEntity
{
ProviderId = g.Key.ProviderId,
Codes = g.OrderByDescending (x => x.Volume).Take(5).ToList()
};
最好斯科特
为了让 LINQ 生成兼容的代码,我们简单地编辑了生成的 EDMX 文件(不要尖叫,继续阅读)。
我们发现(在第 7 行)
<Schema Namespace="ComplianceRiskModel.Store" ProviderManifestToken="2012" Provider="System.Data.SqlClient" ...>
并将其更改为
<Schema Namespace="ComplianceRiskModel.Store" ProviderManifestToken="2008" Provider="System.Data.SqlClient" ...>
为了防止每次从数据库刷新模型时都丢失此设置,我们将添加一个生成任务以自动更新 BeforeBuild 目标中的 EDMX 文件,如 http://www.programmingmotility.com/2011/05/setting-providermanifesttoken-for-sql.html 中所述
最好斯科特