【问题标题】:IQueryable to List可查询列表
【发布时间】:2014-08-22 18:14:25
【问题描述】:

我使用System.Linq.Dynamic 允许我从这样的查询中动态选择字段列表:

finalQuery = query.Select(string.Format("new({0})", string.Join(",", selectors)));

selectors 只是一个 List<string>,其中包含我想要的所有字段。这很好用,但是这个版本的扩展方法Select 返回一个IQueryable。这不是不是IQueryable<T>。如果我有IQueryable<T>,我可以简单地执行.ToList() 将其转换为列表并强制查询在数据库上实际运行,但对于非通用IQueryable,该方法不存在。

这是因为ToList 继承自IEnumerable<T>IQueryable<T> 继承而IQueryable 显然没有。

那么让IQueryable 执行查询并返回列表的最有效方法是什么?我可以这样做:

List<object> rtn = new List<object>();
foreach (var o in finalQuery)
{
    rtn.Add(o);
}

但似乎他们应该是一种更简单的方法。

编辑:根据建议,我都尝试了:

finalQuery.Cast<object>().ToList();

和:

finalQuery.Cast<dynamic>().ToList();

两者都给NotSupportedExceptions 发送消息:

Unable to cast the type 'DynamicClass1' to type 'System.Object'. LINQ to Entities 
only supports casting EDM primitive or enumeration types.

【问题讨论】:

标签: c# linq


【解决方案1】:

这似乎是 LINQ to Entities 将 IQueryable.Cast 转换为匿名类型的方式的限制。您可以通过将其用作IEnumerable 来解决此问题(您的工作示例就是这样做的)。这会导致代码在 .NET 运行时中进行转换从数据库中检索到之后,而不是尝试在数据库引擎中处理它。例如

IEnumerable finalQuery = query.Select(string.Format("new({0})",
                                                   string.Join(",", selectors)));
var result = finalQuery.Cast<dynamic>().ToList();

或者

public static IList<T> CastToList<T>(this IEnumerable source)
{
    return new List<T>(source.Cast<T>());
}

var finalQuery = query.Select(string.Format("new({0})",
                                            string.Join(",", selectors)));
var result = finalQuery.CastToList<dynamic>();

【讨论】:

  • 我确信您对 Linq 到实体和匿名类型的问题的分析是正确的,但我已经尝试过 Cast&lt;dynamic&gt;(),这给了我一个 NotSupportedException。执行foreach 似乎是唯一有效的方法,这有点奇怪。
  • @MattBurland 当编译时类型为IQueryable 并且您执行Cast&lt;&gt; 时,它调用的方法与IEnumerable 不同。当它是 IQueryable 时,它告诉 LINQ to Entities 它想要转换。当它是IEnumerable 时,它的作用类似于您的foreach
  • 啊!我错过了你有IEnumerable 而不是IQueryable。切换确实有效。谢谢。
  • 这可能有效,但将 Linq 避开到实体并仅返回完整的结果集并不是解决方案。如果这是在另一个连接和许多其他操作之前出现的连接,那么您最终会在应用程序而不是数据库中运行这些后续操作,这违背了使用 Linq to Entities 的目的。关键是将代码转换为可以在数据库服务器中运行的数据库查询,以便在将结果发送到应用程序之前缩小结果范围,而不是预先发送所有数据。
猜你喜欢
  • 1970-01-01
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多