能否为LinqDataSource添加查询提示?遗留ASP.NET应用性能优化
为LinqDataSource添加SQL查询提示的方法
LinqDataSource本身没有直接配置查询提示的属性,但可以通过拦截查询执行过程的方式添加OPTION (USE HINT ('FORCE_LEGACY_CARDINALITY_ESTIMATION'))提示,具体步骤如下:
1. 修改LinqDataSource标记,绑定Selecting事件
在原有LinqDataSource配置中添加OnSelecting事件处理器:
<asp:LinqDataSource ID="MyDataSource" runat="server" ContextTypeName="MyDataContext" OrderBy="Column1, Column2" TableName="MyTable" Where="MyId == @Pid && Oid == @Oid" OnSelecting="MyDataSource_Selecting"> <!-- 添加此行 --> <WhereParameters> <asp:Parameter DefaultValue="1" Name="Pid" Type="Int32" /> <asp:Parameter DefaultValue="1" Name="Oid" Type="Int32" /> </WhereParameters> </asp:LinqDataSource>
2. 在代码后台实现Selecting事件处理器
通过拦截LinqDataSource的查询生成过程,为最终执行的SQL命令追加查询提示:
protected void MyDataSource_Selecting(object sender, LinqDataSourceSelectEventArgs e) { using (var context = new MyDataContext()) { // 获取LinqDataSource生成的查询对象 var targetQuery = e.Query as IQueryable<MyTable>; if (targetQuery == null) return; // 获取对应的SQL命令 DbCommand sqlCommand = context.GetCommand(targetQuery); // 为命令文本追加查询提示 sqlCommand.CommandText += @" OPTION (USE HINT ('FORCE_LEGACY_CARDINALITY_ESTIMATION'))"; // 执行修改后的查询并转换为实体列表 if (context.Connection.State != ConnectionState.Open) { context.Connection.Open(); } using (DbDataReader reader = sqlCommand.ExecuteReader()) { var results = context.Translate<MyTable>(reader).ToList(); e.Result = results; // 取消LinqDataSource的默认执行逻辑 e.Cancel = true; } } }
关键说明:
- 此方法保留了LinqDataSource原有参数、排序、筛选等配置,无需手动编写完整SQL
MyTable需与DataContext中映射的视图实体类名称一致- 若LinqDataSource启用分页,查询提示会自动追加到分页SQL末尾,不影响分页逻辑
内容的提问来源于stack exchange,提问作者Jonny
相关产品推荐
相关产品推荐

