这有点难以解释并提供代码示例,所以请耐心等待,如果我不清楚,请提出问题。
我有一种情况,我将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的编写方式,只是因为它可以将这个可查询文件存储在通用对象中。