我可以使用实体框架在一个数据库调用中轻松评估许多IQueryable吗

本文关键字:调用 数据库 评估 IQueryable 许多 一个 实体 可以使 框架 我可以 | 更新日期: 2023-09-27 18:20:29

假设我有一个IQueryable<MyEntity>的集合(任意大小)(全部用于相同的MyEntity类型)。每个单独的查询都已成功地动态构建,以将各种业务逻辑封装到一个表单中,该表单可以在一次数据库访问中进行评估。我现在有没有办法让所有这些IQueryable到数据库的单次往返中执行?

例如(简化了;我的实际查询更复杂!),如果我有

ObjectContext context = ...;
var myQueries = new[] {
    context.Widgets.Where(w => w.Price > 500),
    context.Widgets.Where(w => w.Colour == 5),
    context.Widgets.Where(w => w.Supplier.Name.StartsWith("Foo"))
};

我想让EF执行每个查询的翻译(它可以单独完成),然后在一次数据库访问中,执行

SELECT * FROM Widget WHERE Price > 500
SELECT * FROM Widget WHERE Colour = 5
SELECT W.* FROM Widget 
                INNER JOIN SUpplier ON Widget.SupplierId = Supplier.Id 
           WHERE Supplier.Name LIKE 'Foo%'

然后将每个结果集转换为IEnumerable<Widget>,以通常的方式更新ObjectContext

我看到过关于处理存储过程中的多个结果集的各种帖子,但这略有不同(尤其是因为我不知道在编译时会有多少结果集)。有没有一种简单的方法,或者我必须使用类似"实体框架是否支持具有返回多个结果集的单个存储过程的能力?"??

我可以使用实体框架在一个数据库调用中轻松评估许多IQueryable吗

否。EF没有查询批处理(将来的查询)。一个可查询的是一个数据库往返。作为一种变通方法,你可以尝试使用它,例如使用:

string sql = ((ObjectQuery<Widget>)context.Widgets.Where(...)).ToTraceString();

获取查询的SQL,并从所有要执行的SQL中构建自己的自定义命令。之后,您可以使用与存储过程类似的方法来转换结果。

除非您真的需要分别执行每个查询,否则您也可以将它们合并为一个查询:

context.Widgets.Where(...).Union(context.Widgets.Where(...));

这将导致UNION。如果您只需要UNION ALL,则可以使用Concat方法。

这可能是一个迟来的答案,希望它能帮助其他人解决同样的问题。

NuGet上有实体框架扩展库,它提供了未来的查询功能(以及其他功能)。我用它打了一点球,看起来很有希望。

你可以在这里找到更多信息。