我正在尝试创建一个接受集合对象的泛型方法,该对象类型的字符串表示形式以及一个字符串(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 Object
,ByVal data as MyStrongType
)并执行等效的动态linq查询,它就可以了。但似乎输入Object
,即使转换成功(已在调试会话中确认),我也会收到此错误。
请注意,集合类型是自定义对象(SharePoint CSOM对象,如果有帮助的话),而不仅仅是List(Of T)
。
答案 0 :(得分:1)
进一步考虑,Select
的DLINQ版本实际上必须要求IEnumerable
或IQueryable
而不是IEnumerable(Of T)
。我已经快速查看了,但无法找到确认信息,但我认为必须是这种情况,否则它不会是动态的。在这种情况下,您可以简单地转换为该类型,这不需要对代码进行任何其他更改。
如果只需要IEnumerable
,那么请使用:
Dim result = DirectCast(data2, IEnumerable).Select(selectVars)
如果需要IQueryable
,那么,由于您的对象可能尚未实现,因此您需要:
Dim result = DirectCast(data2, IEnumerable).AsQueryable().Select(selectVars)
这个答案是一个有根据的猜测,但似乎合乎逻辑,所以希望它是准确的。