【问题标题】:Mixing raw SQL with IQueryable for dynamic filter将原始 SQL 与 IQueryable 混合用于动态过滤
【发布时间】:2019-10-07 15:25:34
【问题描述】:

在实体框架 6 中,是否可以像这样将动态生成的原始 SQL 与 IQueryable 混合:

IQueryable<Tree> tree_query = context.Trees.Where(t=>t.Height> 2);
IEnumerable<int> tree_additional_filter = context.Database.SqlQuery<int>("SELECT Id FROM TREE_VIEW WHERE Width < 1");

IQueryable<Tree> final_query = from tree in tree_query 
                               join filtering_tree in tree_additional_filter on filtering_tree.id equals tree.id
                               select tree;

这会按原样产生结果,但会在数据库中执行“tree_additional_filter”以构造 final_query。如何让实体框架只构造一个查询?

我需要它来创建与静态过滤器字段一起使用的动态过滤器字段。

我还尝试创建只有 Id 列的 TREE_VIEW 实体,我知道它始终存在。 使用 System.Linq.Dynamic 在只有 Id 属性的 TREE_VIEW 实体上动态构造“where”子句,但如果 Type 中不存在属性,则显然无法构建表达式。

【问题讨论】:

  • 此代码混合查询。这是两个单独的查询。第一次查询的结果存放在tree_additional_filter
  • 如何使 tree_additional_filter 成为 Iqueryable 以添加到其他查询?

标签: c# sql entity-framework-6 system.linq.dynamic


【解决方案1】:

我成功了。

  1. 使用Dynamic type generation 从我从TREE_VIEW 中选择top 1 的字段中创建一个类型(NewDynamicType)。通过OnModelCreating 中的DbModelBuilder.RegisterEntityTypeNewDynamicType 附加到数据库上下文。
  2. 使用System.Linq.Dynamic,然后我可以构造IQueryable,从context.Set(NewDynamicType) 中选择用户想要过滤的任何字段。
  3. 像我的问题一样加入final_query

现在我的 HTML 表单从数据库视图中获取字段,并且在每个分布中我可以定义不同的过滤器,而无需编写任何 c#。

【讨论】:

  • 发布您的代码。
【解决方案2】:

在实体框架 6 中,是否可以像这样将动态生成的原始 SQL 与 IQueryable 混合:

没有。请注意,Database.SqlQuery 返回的是 IEnumerable&lt;T&gt;,而不是 IQueryable&lt;T&gt;。因此,将使用 LINQ to Objects 针对查询结果执行任何其他查询表达式。

Query Composition with raw SQL 查询是在 EF Core 中引入的。

【讨论】:

  • 我是否可以使用反射来动态构建 tree_view 实体并将其附加到上下文中,以便我可以欺骗实体框架来构建查询?通过动态 linq 还是其他方式?
猜你喜欢
  • 2011-03-26
  • 2011-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多