是否投射导致 IQueryable 在 Linq-to-SQL 中进行评估?其使用有哪些限制?
Cast 是否会导致 IQueryable 在 Linq-to-SQL 中进行计算?
其使用有哪些限制?
看起来如果我为记录创建显式转换为域对象,例如:
IQueryable<TSqlRecord> q;
var cast = q.Cast<TDomainObject>();
那么我应该收到错误,因为 Linq-to-Sql 显然无法处理域对象构造函数。
但是,我可以将 IQueryable
转换为其接口 IHasIntId
而不强制查询进行评估吗?
Does Cast cause an IQueryable to evaluate in Linq-to-SQL?
What are the restrictions on its use?
It seems like if I created an explicit conversion for a record to a domain object like:
IQueryable<TSqlRecord> q;
var cast = q.Cast<TDomainObject>();
Then I should get an error, because Linq-to-Sql and obviously can't process the domain object constructor.
But, can I cast IQueryable<TSqlRecord>
to its interface IHasIntId
without forcing the query to evaluate?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
强制转换是延迟的,不会立即执行。这是因为它(本身)没有枚举源。仅当枚举某些内容时,才会运行查询。
向上转型是没有问题的。查询将正常工作。
回想一下 - 查询适用于数据库行而不是实例。仅当行到达本地时才会创建实例。对cast 的调用所做的只是更改结果中使用的引用类型 - 它不会更改新实例的类型。
但是 - 这并不是真正有用 - 因为行上的属性位于原始类型上,现在您无法在查询的其余部分引用这些属性。
贬低其实并没有多大作用。 LinqToSql 假定每行都是
Table
中的 T 类型。不是什么TChild。这将生成一个查询,为表中的每一行选择 null。隐式转换……对此应该非常小心。即使 LinqToObject 的
Enumerable.Cast
也不尊重隐式转换操作(请参阅 此处 和 此处)。当然,这与 LinqToSql 没有任何关系 - 但原则很重要 - .net 转换与 c# 隐式转换和任何 sql 事物不同。您必须记住您正在编写的代码的执行环境。Cast is deferred and does not cause immediate execution. This is because it does not (itself) enumerate the source. Only when something is enumerated, is the query run.
Upcasting is no problem. The query will work fine.
Recall - the query works on database rows and not on instances. Instances are only created when the rows arrive locally. All that this call to cast does is to change the reference type used in the result - it doesn't change the type of instance new'd up.
But - that's not really useful - as the properties on the row were on the original type and now you can't refer to those properties in the rest of the query.
Downcasting doesn't really do much. LinqToSql presumes that the each row is of type T from the
Table<T>
. Not some TChild. This will generate a query selecting null for each row from the table.Implicit conversion... one should be very careful with that. Even LinqToObject's
Enumerable.Cast<T>
doesn't respect implicit conversion operations (see here and here). Of course, that doesn't have anything to do with LinqToSql - but the principle matters - .net casting is not the same as c# implicit conversion and whatever sql thing. You must bear in mind the execution environment of the code you're writing.不可以,您无法将
IQueryable
转换为IHasIntId
,因为IQueryable
表示TSqlRecord< 类型的多个对象/code>,而
IHasIntId
仅代表一个对象。至少,这就是我对你的样本的理解。我认为,你的问题应该这样问:
这个问题的答案是:不,这是不可能的
MSDN 声明如下:
这意味着,对
Cast
的调用并未真正执行,而是由查询提供程序解释,例如转换为 SQL。No, you can't cast
IQueryable<TSqlRecord>
toIHasIntId
, becauseIQueryable<TSqlRecord>
represents multiple objects of typeTSqlRecord
, whereasIHasIntId
only represents one object. At least, that's how I understand your sample.I think, your question should have been asked like this:
The answer to that question is: No, it's not possible
MSDN states the following:
This means, that the call to
Cast
is not really executed, but interpreted by the query provider and for example translated into SQL.