为什么这个IQueryable.Where <tsource>调用返回的类型不同于IQueryable <tsource>?</tsource> </tsource>

时间:2014-09-10 23:26:59

标签: c# generics linq-to-sql iqueryable

这有点难以解释并提供代码示例,所以请耐心等待,如果我不清楚,请提出问题。

说明

我有一种情况,我将IQueryable<T>(使用LINQ-to-SQL)传递给通用方法,然后在.Where的副本上调用IQueryable。通用方法可以由两个不同的代码路径中的任何一个调用。在其中一个代码路径中,.ElementType的{​​{1}}在IQueryable调用后发生了更改,但在另一个代码路径中保持不变。我在发生变化的情况下遇到错误,我不需要这样做。

代码

我有一个名为Where的类型,它继承自InventoryGridQueryElement,沿着以下几行:

PivotGridQueryElement

另一个类创建public class InventoryGridQueryElement : PivotGridQueryElement { public int IId { get; set; } ... other simple public properties } 。在一个执行路径中,即创建问题的路径,此对象保存在IQueryable<InventoryGridQueryElement>变量中,然后将该变量传递给泛型方法。在另一个执行路径中,传递给泛型方法的变量仍然是Object

两个执行路径首先调用此方法,IQueryable<InventoryGridQueryElement>(或IQueryable<InventoryGridQueryElement>)作为Object参数传入:

dataSource

然后调用

protected DataTableAndPaging FilterDataSource<T>( IQueryable<T> dataSource, NameValueCollection queryString ) where T : PivotGridQueryElement {

iqueryable = iqueryable.FilterByQueryString( this, queryString );

包括这两行

public static IQueryable<T> FilterByQueryString<T>( this IQueryable<T> iQ, Grid grid, NameValueCollection query ) where T : PivotGridQueryElement {

实际问题

这两行中的第二行var copy = iQ; ... copy = copy.Where( pgr1 => iQ.Where( pgr2 => pgr2.Key == pgr1.Key && pgr2.DataField == column.DataField && pgr2.ColumnText.Contains( requestValue ) ).Any() ); 是问题发生的地方。在有问题的执行路径中,如果我在copy.Where上设置监视,那么在执行此行之前我有

copy.ElementType

然后在踩过线后我

+       copy.ElementType    {Name = "InventoryGridQueryElement" FullName = "ProjectNamespace.Models.GridModelInventory+InventoryGridQueryElement"}  System.Type {System.RuntimeType}

在另一个执行路径中,一切正常,我在执行+ copy.ElementType {Name = "PivotGridQueryElement" FullName = "ProjectNamespace.Models.PivotGridQueryElement"} System.Type {System.RuntimeType} 行之前和之后都有第一个观察结果。

实际执行查询后,会引发错误,因为查询涉及copy.Where的{​​{1}}属性,但.IId没有此类属性。

更新

我决定尝试使用其他方法跟踪InventoryGridQueryElement的类型,而不是观看PivotGridQueryElement。我切换到Locals窗口,查看了每个copy和iQ列出的类型。即使iQ.ElementType和copy.ElementType都是T,iQ和copy也会在问题路径中列为IQueryable.ElementType。在成功路径中,它们都列为IQueryable<PivotGridQueryElement>

然后我在查询之前和之后添加了这些行:

InventoryGridQueryElement

在良好的道路上,IQueryable<InventoryGridQueryElement> == Type copyType1 = copy.GetType().GetGenericArguments()[ 0 ]; Type elementType1 = copy.ElementType; copy = copy.Where( pgr1 => iQ.Where( pgr2 => pgr2.Key == pgr1.Key && pgr2.DataField == column.DataField && pgr2.ColumnText.Contains( requestValue ) ).Any() ); Type copyType2 = copy.GetType().GetGenericArguments()[ 0 ]; Type elementType2 = copy.ElementType; == copyType1 == elementType1 == copyType2

在错误的路径中,elememtType2 == InventoryGridQueryElement == copyType1,但elementType1 == InventoryGridQueryElement == copyType2。< / p>

再次更新:

我写了一个简短的独立控制台程序来重现这个问题。我问a new question只提到了那个例子,没有这个问题,对复杂的elementType2查询或LINQ-to-SQL的其他问题。

问题

那么,PivotGridQueryElement来电可能会导致.Where来电更改.Where的{​​{1}}?这些原因中的任何一个似乎都与我的具体情况有关吗?

注意:此代码与我们正在使用的第三方API紧密结合。我不喜欢API的编写方式,只是因为它可以将这个可查询文件存储在通用对象中。

0 个答案:

没有答案