动态 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 Object
、ByVal data as MyStrongType
)并执行等效的动态 linq 查询,它就可以正常工作。但是似乎进行输入 Object
,即使转换成功(已在调试会话中确认),我仍收到此错误。
请注意,集合类型是自定义对象(SharePoint CSOM 对象,以防万一),而不仅仅是 List(Of T)
。
进一步考虑,Select
的 DLINQ 版本实际上必须需要 IEnumerable
或 IQueryable
而不是 IEnumerable(Of T)
。我快速浏览了一下,但找不到确认信息,但我认为一定是这样,否则就不会是动态的。在这种情况下,您可以简单地转换为该类型,不需要对您的代码进行任何其他更改。
如果只需要 IEnumerable
,那么使用这个:
Dim result = DirectCast(data2, IEnumerable).Select(selectVars)
如果需要 IQueryable
,因为您的对象可能还没有实现它,您需要这个:
Dim result = DirectCast(data2, IEnumerable).AsQueryable().Select(selectVars)
这个答案是一个有根据的猜测,但它似乎合乎逻辑,所以希望它是准确的。
我正在尝试创建一个通用方法,它接受一个集合对象、一个对象类型的字符串表示,以及一个字典(包含字符串、字符串),其键包含感兴趣的属性。
然后我想根据这些输入生成动态 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)
。
进一步考虑,Select
的 DLINQ 版本实际上必须需要 IEnumerable
或 IQueryable
而不是 IEnumerable(Of T)
。我快速浏览了一下,但找不到确认信息,但我认为一定是这样,否则就不会是动态的。在这种情况下,您可以简单地转换为该类型,不需要对您的代码进行任何其他更改。
如果只需要 IEnumerable
,那么使用这个:
Dim result = DirectCast(data2, IEnumerable).Select(selectVars)
如果需要 IQueryable
,因为您的对象可能还没有实现它,您需要这个:
Dim result = DirectCast(data2, IEnumerable).AsQueryable().Select(selectVars)
这个答案是一个有根据的猜测,但它似乎合乎逻辑,所以希望它是准确的。