强制转换 IQueryable到 IQueryable
我们尝试将 IQueryable
实例转换为 IQueryable
,SpecificEntityObject
类型仅在运行时已知。
我们尝试使用下面的代码,但该代码无法编译,因为类型或命名空间“objType”不存在。
var t = query.ElementType;
Type objType = typeof(IQueryable<>).MakeGenericType(t);
var typed = query.Cast<IEnumerable<objType>>();
var grouped = typed.GroupByMany(groupBy.Select(grp => grp.Expression).ToArray());
有什么想法吗?
We are trying to cast an instance of IQueryable<EntityObject>
to an IQueryable<SpecificEntityObject>
, the SpecificEntityObject
type is only known at runtime.
We have tried using the code below, which does not compile because The type or namespace 'objType' does not exist.
var t = query.ElementType;
Type objType = typeof(IQueryable<>).MakeGenericType(t);
var typed = query.Cast<IEnumerable<objType>>();
var grouped = typed.GroupByMany(groupBy.Select(grp => grp.Expression).ToArray());
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用以下 IQueryable 扩展通用方法
query.ToDTO();
:Use following IQueryable extension generic method
query.ToDTO<sourceType,DestType>();
:对于任何其他想要从数据库查询投影非数据库值的人,this< u/Luis Aguilar 的 /a> 项目对我非常非常有帮助。
我有一个非常大的旧数据库 (450GB),需要将其提供给 OData/WebAPI。
OData 要求意味着我在将源数据返回给用户之前无法(过多)过滤源数据。我们可以将其隔离,但除此之外,这是他们可以按照自己的意愿查询的数据。
然而,更重要的是,遗留数据过于复杂,无法按原样公开,并且需要大量的业务逻辑来整理必要的数据(导航属性/外键的
包括
、冗长的子句谓词、 ETC)。这意味着分页和结果限制在查询已经具体化之前才可用。
此类事情的正常快捷方式涉及涉及物化/渴望加载的各种策略。然而,由于数据集的大小和缺乏过滤,这将导致大量的进程内存膨胀和内存不足崩溃。
所以,一些代码。这是我的配置调用,类似于 AutoMapper 或 OData 的要求:
这种设计允许我将投影规则与其余业务逻辑一起保留在 DTO 类中。 DTO 级代码如下所示:
其中
Client
是我的实体/EDM 类型,映射到数据库表和无数外键。然后,为了获得翻译/投影的
Queryable
,就是这样:只有最后两行是相关的,但包含了上下文的其余部分。
我要做的最后一件事是在 Luis 代码中的
ProjectionSourceTypeConfiguration.cs
的构造函数中设置this.IsAutoConfigured = false;
;这允许我手动订购投影定义,以便父类中的导航属性可以成功配置其投影。我对 https://stackoverflow.com/users/543712/luis-aguilar 他的工作感激不尽。在使用各种通用方法调用、转换和树形遍历编写了我自己的 LINQ Provider/
ExpressionVisitor
之后,仍然存在各种问题,他的项目是天赐之物。如果您确实发现出于性能或其他原因必须管道化自己的表达式处理,我建议这些 首先有两个答案。
For anyone else wanting to to project non-db values from a db query, this project from u/Luis Aguilar was very, very helpful to me.
I had a very large legacy database (450GB) which was required to be served to OData/WebAPI.
The OData requirement meant I could not filter the source data (much) before returning it to the user. We could silo it, but apart from that it is their data to query as they wish.
More importantly, however, the legacy data was far too convoluted to expose as-is, and there was significant business logic required to collate the necessary data (
Include
of navigation properties/foreign keys, lengthy clause predicates, etc).This meant the pagination and result limiting would not be available until after the query was already materialized.
Normal shortcuts for this kind of thing involve various strategies that involve materialization/eager loading. However, due to the size of the dataset and lack of filtering, this would result in massive process memory bloat and out-of-memory crashes.
So, some code. Here's my config call, similar to what AutoMapper or OData require:
This design allows me to keep the projection rules in the DTO class with the rest of the business logic. Here's what the DTO-level code looks like:
Where
Client
is my Entity/EDM type, mapped to db table and a gazillion foreign keys.To then get a translated/projected
Queryable
, this is it:Only the last two lines are relevant, but included the rest for context.
The last thing I had to do was set
this.IsAutoConfigured = false;
in the constructor forProjectionSourceTypeConfiguration.cs
in Luis' code; this allowed me to order my projection definitions manually so navigation properties inside parent classes would configure their projections successfully.I can't thank https://stackoverflow.com/users/543712/luis-aguilar enough for his work. After writing my own LINQ Provider/
ExpressionVisitor
with various generic method invocations, translations and treewalks to still have various problems, his project was a godsend.If you do find to have to pipeline your own expression processing for performance or other reasons, I'd recommend these two answers to begin with.
如果您没有编译时类型信息,则必须一直依赖丑陋的反射代码。
dynamic
关键字可能会让事情变得更整洁。尝试类似的方法:还有一个不错的小扩展方法:
在 System.Linq.Dynamic.Core 库中。
If you don't have compile time type info, you have to rely on ugly reflection code all the way down.
dynamic
keyword might make things a bit tidy. Try something like:There is also nice little extension method:
in
System.Linq.Dynamic.Core
library.如果您开始使用反射,那么您也需要将它与所有方法一起使用。 需要在运行时创建
因此,您还
并查找扩展方法 Cast 匹配所需的类型。那么你就可以调用该方法
If you started using reflection, you need to use it with all methods too. So you need to create
and also find extention method Cast matching needed type also at runtime.
then you would be able to call that method