Linq to entities根据子项选择记录

时间:2014-10-20 15:54:43

标签: c# performance linq entity-framework linq-to-entities

我可以像这样代表我的实体模型:

-> Devices
  -> Records
    -> DataValues
      -> DataField
        - Name
      - Value

我想根据以下内容选择记录:

  • DataValue的DataField的名称
  • DataValue的值

记录有多个DataValues。我想检索所有评估为多组Name和Value值的记录。

除此之外,我还在使用实体框架。我一直试图通过以下代码实现这一目标:

Context.Devices.Where(q => q.SerialNumber == serialNumber)
    .Single()
    .DataRecords.Where(w => w.DataString.Prefix.ToLower() == "data")
    .SelectMany(e => e.DataValues)
    .Where(r =>
        (r.DataField.Name == "" && r.Value == "") &&
        (r.DataField.Name == "" && r.Value == ""))
    .Where(t => t.DataField.Name == "")
    .Select(y => Convert.ToDouble(y.Value));

糟糕的是我已经用完了SelectMany部分的RAM ......

无论如何,你们中有人向我提出了如何达到我想要的目标的方法吗?

1 个答案:

答案 0 :(得分:1)

假设您有通过EF公开的父母的链接,如果您在DataValues级别运行查询,并且约束父母,则应该能够将更多工作卸载到您的RDBMS上,如下所示:

var res = Context.DataValues
    .Where(dv => dv.Record.DataString.Prefix.StartsWith("data")
              && dv.Record.Device.SerialNumber == serialNumber
              && (
                  dv.DataField.Name == "quick" && dv.Value == "brown"
               || dv.DataField.Name == "fox" && dv.Value == "dog"
              ))
    .Select(dv => dv.Value)
    .AsEnumerable() // <<== This will bring your data into memory
    .Select(y => Convert.ToDouble(y);

上述查询在将字符串转换为双倍的时间之前不会将数据带入内存,从而最大限度地减少系统内存的压力。这与您的查询不同,查询将特定设备的所有数据都带入内存,并在那里执行过滤。