动态 Linq 和通用对象 - Public 成员 'Select' 未找到类型 T

Dynamic Linq and generic objects - Public member 'Select' on type T not found

我正在尝试创建一个通用方法,它接受一个集合对象、一个对象类型的字符串表示,以及一个字典(包含字符串、字符串),其键包含感兴趣的属性。

然后我想根据这些输入生成动态 linq 查询。似乎即使在将输入集合对象转换为强类型对象之后,动态 linq 也不起作用 - 它说 Public member 'Select' on type '{T}' not found (其中 {T} 是强类型)。

这基本上是我得到的:

Sub Testing123(ByVal data As Object, ByVal fieldDefs As Dictionary(Of String, String), ByVal myObjectType as String, ByVal myCollectionType As String, ByVal myAssembly As String)

    ' Type of object in the collection
    Dim properties = Type.GetType(myObjectType).GetProperties().Where(Function(p) fieldDefs.ContainsKey(p.Name)).ToList()
    ' Get type of the collection object (data)
    Dim thisType = Type.GetType(String.Format("{0},{1}",myCollectionType,myAssembly))
    ' Create strongly-typed collection object
    Dim data2 = Convert.ChangeType(data, thisType)
    ' Resolve select list from input
    Dim selectVars As String = "new (" & String.Join(", ", fieldDefs.Keys.ToList()) & ")"
    ' materialise dynamic query
    Dim result = data2.Select(selectVars) ' ERROR IS HERE

    For Each r In result
        Debug.Print(r.Title & " " & r.ViewType)
    Next
End Sub

如果我传入一个强类型集合对象(例如,而不是 ByVal data As ObjectByVal data as MyStrongType)并执行等效的动态 linq 查询,它就可以正常工作。但是似乎进行输入 Object,即使转换成功(已在调试会话中确认),我仍收到此错误。

请注意,集合类型是自定义对象(SharePoint CSOM 对象,以防万一),而不仅仅是 List(Of T)

进一步考虑,Select 的 DLINQ 版本实际上必须需要 IEnumerableIQueryable 而不是 IEnumerable(Of T)。我快速浏览了一下,但找不到确认信息,但我认为一定是这样,否则就不会是动态的。在这种情况下,您可以简单地转换为该类型,不需要对您的代码进行任何其他更改。

如果只需要 IEnumerable,那么使用这个:

Dim result = DirectCast(data2, IEnumerable).Select(selectVars)

如果需要 IQueryable,因为您的对象可能还没有实现它,您需要这个:

Dim result = DirectCast(data2, IEnumerable).AsQueryable().Select(selectVars)

这个答案是一个有根据的猜测,但它似乎合乎逻辑,所以希望它是准确的。