【问题标题】:How to use ToDictionary to convert a query result into a dictionary如何使用 ToDictionary 将查询结果转换为字典
【发布时间】:2017-12-27 00:53:51
【问题描述】:

我在 EF 中有这个查询:

var data = db.Inventario.Where(i => i.ClienteId.Equals(Global.ClienteID))
   .GroupBy(i => new { Tipo = i.Tipo.TipoNombre, Zona = i.Localidad.Zona.ZonaNombre, Localidad = i.Localidad.LocalidadNombre })
   .Select(i => new Registro()
      {
         Tipo = i.Key.Tipo,
         Zona = i.Key.Zona,
         Localidad = i.Key.Localidad,
         Estados = i.SelectMany(ei => ei.EstadoInventario)
            .GroupBy(ei => ei.Estado.EstadoNombre)
            .AsEnumerable()
            .ToDictionary(ei => ei.Key, ei => ei.Sum(item => item.EstadoInventarioValor ? 1 : 0))
      });

this.Data = data.ToList();

当我运行它时,会出现这个错误:

LINQ to Entities 无法识别该方法 'System.Collections.Generic.Dictionay`2[System.String,System.Int32] ToDictionary[IGrouping`2,String,Int32](System.Collections.Generic.IEnumerable`1[System.Linq.IGrouping`2[System.String,Data.EstadoInventario]], System.Func`2[System.Linq.IGrouping`2

Registro 类的 Estados 属性是一个 Dictionary,我需要在其中存储一个键为 EstadoNombre 的字典,其中包含查询结果中记录总和的值。

【问题讨论】:

  • ToDictionary 之前放置一个AsEnumerable() 以首先从服务器拉取结果。
  • 它没有用。我已经更新了这个问题。 data.ToList() 指令出错
  • 抱歉,我没有注意到您在 Select 中包含 ToDictionary - 将 ToEnumerable 移到 Select 之前。这可能会对性能产生影响。请注意,调用GroupBy 后跟ToDictionary 可能不是最有效的做法。根据服务器性能,我会将AsEnumerable 放在第一个GroupBy 之前,以将服务器查询减少到一个。

标签: c# entity-framework linq dictionary


【解决方案1】:

LINQ to Entities 将您的 LINQ 表达式转换为 SQL 语句(或基于您的提供程序的任何其他内容),从而为您提供所需的数据。但是,并非所有表达式都可以轻松转换为 SQL(即ToDictionary 函数调用),这就是运行时抱怨的原因。

因此,在使用任何这些无法识别的表达式之前,您必须具体化您的查询(即从数据库中获取数据并将其转换为对象)。

为此,您只需在您的IQueryable 上调用ToList() 以从您的查询 中获取对象列表,然后您就可以在该对象列表上调用ToDictionary .

我没有测试下面的代码,但它描述了这个想法。

var query = db.Inventario.Where(i => i.ClienteId.Equals(Global.ClienteID))
                .GroupBy(i => new { Tipo = i.Tipo.TipoNombre, Zona = i.Localidad.Zona.ZonaNombre, Localidad = i.Localidad.LocalidadNombre })
                .Select(i => new { Tipo = i.Key.Tipo, Zona = i.Key.Zona, Localidad = i.Key.Localidad, Estados = i.SelectMany(ei => ei.EstadoInventario).GroupBy(ei => ei.Estado.EstadoNombre) });

var data = query.ToList().Select(i => new Registro { Tipo = i.Tipo, Zona = i.Zona, Localidad = i.Localidad, Estados = i.Estodas.ToDictionary(ei => ei.Key, ei => ei.Sum(item => item.EstadoInventarioValor ? 1 : 0)) });

【讨论】:

  • 唯一的问题是性能.....我想我应该实现另一种技术
  • @jstuardo 将数据分成块可能会有所帮助
猜你喜欢
  • 2010-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多