执行不良的查询需要重写
本文关键字:重写 查询 不良 执行 | 更新日期: 2023-09-27 18:00:23
我有一段代码执行不好,需要重新编写它,以便在启动.ToList之前引入一个适当的where子句。然而,这就是我遇到的问题。
目前代码看起来像这样(大致上,我已经去掉了一些搜索标准,使其更容易显示)
var Widgets = from b in _caspEntities.Widgets.Include("WidgetRegionLogs")
.Include("WidgetStatusLogs").Include("WidgetVoltageTests")
select b;
IEnumerable<Widget> results = Widgets.ToList();
if (comboBoxRegion.SelectedValue.ToString() != "0")
{
results = from b in results
where b.CurrentRegionLog != null && b.CurrentRegionLog.RegionId == int.Parse(comboBoxRegion.SelectedValue.ToString())
select b;
}
if (comboBoxStatus.SelectedValue != null)
{
results = from b in results
where b.CurrentStatusLog != null && b.CurrentStatusLog.StatusId == comboBoxStatus.SelectedValue.ToString()
select b;
}
if (txtCode.Text.Trim().Length > 0)
{
results = from b in results
where b.CodeNumber == txtCode.Text.Trim()
select b;
}
dataGridViewWidget.DataSource = results.ToList();
我可以很容易地编写SQL,本质上模型很简单,我有一个Widget,它有一个RegionLog和一个StatusLog,两者都存储历史。通过按WidgetID分组并选择最近的更新日期(然后转到region和status表以获得实际值),可以从中检索当前区域和状态。
所以,我需要把这个翻译成LINQ,但说实话,我不知道,但我很愿意学习。在我的脑海中,我认为我需要添加一些更好的where子句,然后在应用了where子句后执行Widget.toList。我很难理解CurrentRegionLog
和CurrentStatusLog
的概念,因为在运行IEnumerable
之前,它们不会被填充。
如果有人能给我一些建议,我将不胜感激,感谢
编辑-添加
public BatteryRegionLog CurrentRegionLog
{
get { return _currentRegionLog; }
}
private BatteryRegionLog _currentRegionLog
{
get
{
if (this.BatteryRegionLogs.Count > 0)
{
BatteryRegionLog log = this.BatteryRegionLogs.OrderByDescending(item => item.LastModifiedDate).First();
return log;
}
else
{
return null;
}
}
}
您可以这样编写查询:
if (comboBoxRegion.SelectedValue.ToString() != "0")
{
var id = int.Parse(comboBoxRegion.SelectedValue.ToString()
Widgets = from b in Widgets
let currentRegionLog =
b.BatteryRegionLogs
.OrderByDescending(item => item.LastModifiedDate)
.FirstOrDefault()
where currentRegionLog.RegionId == id)
select b;
}
... // Same for the other criteria.
dataGridViewWidget.DataSource = Widgets.ToList();
在执行ToList()
之前,不会执行整个查询。由于所有内容都被转换为SQL,所以不需要空检查b.CurrentRegionLog != null
。当不存在CurrentRegionLog
时,SQL将对b.CurrentRegionLog.RegionId == id
进行良好的评估。
编辑
由于CurrentRegionLog
是Widget
类的计算属性,因此无法将其转换为SQL。我努力将计算属性的代码合并到查询中,只使用基本的导航属性,这样EF就可以再次将其转换为SQL。
尝试删除此行:
IEnumerable<Widget> results = Widgets.ToList();
只需使用顶部中的Widgets
变量
.ToList()
进入数据库并将所有数据实体化。
如果不调用.ToList()
,则对于where
子句的查询仍然是"打开的"