Mar*_*tao 5 linq vb.net dynamic vb.net-2010
我正在尝试使用Dynamic Linq进行一些测试,但是对它不熟悉,我遇到了麻烦.
目前我有一个DataTable对象,我已经通过SQL查询填充到数据库.现在我想在这个DataTable上执行动态linq查询.这可能看起来不合逻辑,但我的最终目标是能够在由两个不同数据库填充的两个不同的DataTable上执行连接,所以考虑到这一点,我希望它更有意义.在我继续解决这个主要问题之前,我正在尝试理解一个更简单的情况并进行一些实验.
问题一是我不完全确定IQueryable(Of T)和IEnumerable(Of T)之间的选择.我理解的方式是,如果你在内存中做所有事情,你选择IEnumerable.我认为那适合我的情况,对吗?但是,当我看到更改IQuerbyable中的IEnumerable时(在下面的代码片段中),我惊讶地发现"x.Item(Fieldname)"不起作用!?我错过了什么?它给出的错误是:"后期绑定操作无法转换为表达式树".
无论如何,让我们来看看.我已经有部分工作了:
Dim desc As String = "Description"
Dim status As String = "Status"
Dim query As IEnumerable(Of DataRow) = From x In tab.AsEnumerable()
query = query.Where(Function(x As Object) x.Item(status) < 100)
For Each row As DataRow In query.ToList()
'Do something
Next row
Run Code Online (Sandbox Code Playgroud)
这似乎工作正常.我使用了两个字符串变量,因为最后我想动态决定采用哪个字段.所以,"x!描述"不适合我.但是,现在我想在查询中添加一个投影,即选择一些列.我的期望是这应该是这样的:
query = query.Select(Of String)(Function(x As Object) x.Item(desc))
Run Code Online (Sandbox Code Playgroud)
(注意:我使用Select(Of String),因为这个特定的列具有类型.这当然也应该动态填充)
但是,在InvalidCastException运行时期间失败:"无法转换类型为'WhereSelectEnumerableIterator 2[System.Data.DataRow,System.String]' to type 'System.Collections.Generic.IEnumerable1 [System.Data.DataRow]'的对象." 我真的不明白这里发生了什么; 我猜错了,因为我想返回DataRow,但目前只选择一个字段,恰好是一个字符串.谁能解释/帮助我?
提前致谢!
好的,编辑,因为我应该从头开始提供更多信息:我可以有一个可变数量的where-或select-clauses.我的想法是我可以通过循环包含此信息的列表来动态添加这些.所以我认为我需要IEnumerable提供的.Where()和.Select()函数.
您在以下行中声明query其类型:IEnumerable(Of DataRow)
Dim query As IEnumerable(Of DataRow) = From x In tab.AsEnumerable()
Run Code Online (Sandbox Code Playgroud)
现在,您想IEnumerable(Of String)用您的 来创建一个Select,这很好。
但是您尝试将类型为 的结果分配IEnumerable(Of String)给query类型为 的结果IEnumerable(Of DataRow)。
query = query.Select(Of String)(Function(x As Object) x.Item(desc))
Run Code Online (Sandbox Code Playgroud)
由于IEnumerable(Of String)无法转换为IEnumerable(Of DataRow),反之亦然,因此您会得到一个InvalidCastException.
另外,我不知道你为什么Function(x As Object)在你的Whereand中使用Select,更好地使用Function(row As DataRow),因为你已经知道你正在使用 a DataRow。
此外,您的代码可以这样重写:
Dim desc As String = "Description"
Dim status As String = "Status"
Dim columnToUse = status
Dim query = From x In tab.AsEnumerable()
Where x.Item(status) < 100
Select x(columnToUse)
For Each item as String In query.ToList()
'Do something
Next
Run Code Online (Sandbox Code Playgroud)
更改columnToUse将使您能够动态选择所需的字段。
要选择多个字段,您需要返回字典、ExpandoObjects 或元组或类似内容的集合。
例子:
Dim columnToUse = new String() {desc, status} ' select columns dynamically
Dim query = tab.AsEnumerable().Where(Function(row) row.Item(status) < 100)
' Selecting dynamically
Dim result1 = query.Select(function(row) columnToUse.ToDictionary(function(c) c, function(c) row(c)))
Dim result2 = query.Select(Function(row)
Dim exp As IDictionary(Of String, Object) = new ExpandoObject()
For Each column in columnToUse
exp(column) = row(column)
Next
return exp
End Function)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16100 次 |
| 最近记录: |