动态Linq和通用对象 - 未找到类型T上的公共成员“选择”

时间:2018-04-03 04:30:53

标签: .net vb.net linq dynamic dynamic-linq

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

我想基于这些输入生成动态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)

1 个答案:

答案 0 :(得分:1)

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

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

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

如果需要IQueryable,那么,由于您的对象可能尚未实现,因此您需要:

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

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