1

我有一段代码表现不佳,需要重写它以在启动 .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 分组并选择最近的更新日期(然后转到区域和状态表以获取实际值),从中检索当前区域和状态。

所以,我需要把它翻译成 LINQ,但老实说,我没有任何线索,但我很肯并且愿意学习。在我的脑海中,我认为我需要添加一些更好的 where 子句,然后在应用 where 子句后执行 Widget.toList。我正在为CurrentRegionLogCurrentStatusLog概念苦苦挣扎,因为在我运行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;
            }
        }
    }
4

2 回答 2

0

尝试删除这一行:

IEnumerable<Widget> results = Widgets.ToList();

只需使用Widgets您在顶部获得的变量

.ToList()转到数据库并将所有数据具体化为实体。

如果您不调用查询,则子句.ToList()的查询仍然“打开”where

于 2013-02-20T09:51:56.873 回答
0

您可以像这样编写查询:

    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,因此您不需要 null check b.CurrentRegionLog != null。当b.CurrentRegionLog.RegionId == id没有CurrentRegionLog.

编辑

由于CurrentRegionLog是您的Widget类的计算属性,因此无法将其转换为 SQL。我努力将计算属性的代码以仅使用基本导航属性的方式合并到查询中,因此 EF 可以再次将其转换为 SQL。

于 2013-02-20T09:53:19.380 回答